如何在Rails中使用带有嵌套数组的PostgreSQL hstore?

6

迁移:

class Preference < ActiveRecord::Migration

  def change
    enable_extension 'hstore'

    create_table :preferences do |t|
      t.hstore :prefs
    end
  end
end

型号:

class Preference < ActiveRecord::Base
  store_accessor :prefs
end

如果prefs是一个像{ email:'yes' }这样的哈希表,则此方法似乎有效,但对于包含数组的哈希表,则不起作用:{ email:[ 'monday', 'tuesday' ]}

在提取哈希表时,该数组被保存为JSON。

有没有一种好的方法来使用具有嵌套哈希和数组的hstore?

我尝试在迁移中添加array:true,但这只允许保存数组而不是哈希表。

如何将Rails PostgreSQL hstore与嵌套哈希和数组一起使用?

Rails 4.2.4,PostgreSQL 9.3.5

2个回答

9

PostgreSQL hstore用于存储文本字符串的键值对。请查看hstore文档

我使用JSON类型将数组作为值存储在哈希内。有两种JSON数据类型:JSON和JSONB。JSONB支持索引,但速度较慢,而JSON不支持索引,但速度较快。您可以在此处了解有关它们的更多信息:JSON Type

我会这样做:

class Preference < ActiveRecord::Migration
  def change
    create_table :preferences do |t|
      t.json :prefs
    end
  end
end

顺带一提,在hstore列上设置array:true意味着您想存储一个hstore数组。


这是我现在正在使用的解决方案。工作得很好,只是似乎它不支持索引。 - B Seven
1
是的,你说得对。有两种JSON数据类型:json和jsonb。jsonb支持索引。 - Joel
你需要 PostgreSQL 9.4 来使用 jsonb,对吧? - mu is too short
@muistooshort 看起来是这样。我链接的文档是针对9.4版本的。 - Joel

1
您可以在访问时简单解析JSON:
class Preference < ActiveRecord::Base
  def prefs
    self[:pref] = json_parse_values self[:pref]
  end

  private
  def json_parse_values(hash)
    hash.map do |key, val|
      begin
        [key, (val.is_a?(String) ? JSON.parse(val) : val)]
      rescue JSON::ParserError => e  
        [key, val]
      end 
    end.to_h
  end
end

解析方法仅在值为字符串时尝试解析。如果引发ParserError,我们只使用该字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接