Rails 4 Hstore,数组转义引号

时间:2013-11-18 16:58:58

标签: ruby postgresql serialization ruby-on-rails-4 hstore

我正在尝试使用Rails 4和Hstore(Postgres 9.2)存储数组哈希值,以便用户在提交带有大量复选框的表单时使用。我遇到的问题是,一旦存储它们,所有值都会被引用转义,并且在检索时无法读取

irb(main):070:0> Plan
=> Plan(id: integer, email: string, created_at: datetime, updated_at: datetime, first_name: string, professional: boolean, preferences: hstore)
irb(main):070:0> params = {"plan"=>{"first_name"=>"nick", "email"=>"test@test.com", "professional"=                                                                                  z", "gak"], "too"=>["tar", "taz", "tak"], :preferences=>{"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"]}}}
=> {"plan"=>{"first_name"=>"nick", "email"=>"test@test.com", "professional"=>"true"}, "preferences"=>{"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"], :preferences=>{"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"]}}}
irb(main):071:0> plan = Plan.new(params['plan'])                                              => #<Plan id: nil, email: "test@test.com", created_at: nil, updated_at: nil, first_name: "nick", professional: true, preferences: nil>
irb(main):072:0> plan.preferences = params['preferences']
=> {"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"], :preferences=>{"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"]}}
irb(main):073:0> plan
=> #<Plan id: nil, email: "test@test.com", created_at: nil, updated_at: nil, first_name: "nick", professional: true, preferences: {"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"], :preferences=>{"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"]}}>
irb(main):074:0> plan.save
   (0.2ms)  BEGIN
  SQL (1.2ms)  INSERT INTO "plans" ("created_at", "email", "first_name", "preferences", "professional", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["created_at", Mon, 18 Nov 2013 15:44:46 UTC +00:00], ["email", "test@test.com"], ["first_name", "nick"], ["preferences", {"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"], :preferences=>{"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"]}}], ["professional", true], ["updated_at", Mon, 18 Nov 2013 15:44:46 UTC +00:00]]
   (2.4ms)  COMMIT
=> true
irb(main):075:0> plan
=> #<Plan id: 27, email: "test@test.com", created_at: "2013-11-18 15:44:46", updated_at: "2013-11-18 15:44:46", first_name: "nick", professional: true, preferences: {"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"], :preferences=>{"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"]}}>
irb(main):076:0> plan_out = Plan.find(27)
  Plan Load (0.7ms)  SELECT "plans".* FROM "plans" WHERE "plans"."id" = $1 LIMIT 1  [["id", 27]]
=> #<Plan id: 27, email: "test@test.com", created_at: "2013-11-18 15:44:46", updated_at: "2013-11-18 15:44:46", first_name: "nick", professional: true, preferences: {"foo"=>"[\"\", \"bar\", \"baz\", \"bak\"]", "goo"=>"[\"\", \"gar\", \"gaz\", \"gak\"]", "too"=>"[\"tar\", \"taz\", \"tak\"]", "preferences"=>"{\"foo\"=>[\"\", \"bar\", \"baz\", \"bak\"], \"goo\"=>[\"\", \"gar\", \"gaz\", \"gak\"], \"too\"=>[\"tar\", \"taz\", \"tak\"]}"}>
irb(main):077:0> plan.preferences
=> {"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"], :preferences=>{"foo"=>["", "bar", "baz", "bak"], "goo"=>["", "gar", "gaz", "gak"], "too"=>["tar", "taz", "tak"]}}
irb(main):083:0> plan_out.preferences
=> {"foo"=>"[\"\", \"bar\", \"baz\", \"bak\"]", "goo"=>"[\"\", \"gar\", \"gaz\", \"gak\"]", "too"=>"[\"tar\", \"taz\", \"tak\"]", "preferences"=>"{\"foo\"=>[\"\", \"bar\", \"baz\", \"bak\"], \"goo\"=>[\"\", \"gar\", \"gaz\", \"gak\"], \"too\"=>[\"tar\", \"taz\", \"tak\"]}"}
irb(main):085:0> plan_out.preferences['foo']
=> "[\"\", \"bar\", \"baz\", \"bak\"]"
irb(main):086:0> plan_out.preferences['foo'].first
=> "["

所以你可以看到它的实例中的计划很好,但是当从db中检索时,它被转义为hstore并以字符串形式出现。我的计划模型如下所示:

class Plan < ActiveRecord::Base

  store_accessor :preferences, :foo, :goo, :too

  validates :email, presence:true, email_format:true
  validates :professional, :inclusion => {:in => [true, false], :message => "? - Please choose 'Yes' or 'No' for Nutrition Professional"}
end

任何见解都会有所帮助。我想做一些Hstore不能做的事吗?我不想为这些记录做完整的关系数据库,它似乎很适合序列化。

谢谢!

1 个答案:

答案 0 :(得分:1)

据我所知,HSTORE值只是简单的字符串。

这就是文档所说的内容:"Keys and values are simply text strings."

所以你可以自己转换这些值。

另一种可能性是使用Postgres的超级漂亮的JSON功能。那些应该允许本机数组存储。