Is there a way to serialize ActiveRecord's JSON properties using HashWithIndifferentAccess?

自古美人都是妖i 提交于 2019-12-10 16:36:57

问题


I am using ActiveRecord::ConnectionAdapters::PostgreSQLAdapter in a Rails application. Suppose I have a schema:

  create_table "foo", id: :bigserial, force: :cascade do |t|
    t.string   "name"
    t.jsonb    "data",              null: false
  end

Now suppose I run the following code:

class Foo < ActiveRecord::Base
  self.table_name = :foo
end

my_foo = Foo.create!(:name => 'foobar', :data => {:a => 'hello'})
my_foo = Foo.where(:name => 'foobar').first!
puts my_foo.data[:a]
puts my_foo.data['a']

The output would be:

# nil
# 'hello'

Is it possible to ask ActiveRecord to automatically deserialize jsonb types using HashWithIndifferentAccess?


回答1:


| You can use a custom serializer so you can access the JSON object with symbols as well.

# app/models/user.rb
class User < ActiveRecord::Base
  serialize :preferences, HashSerializer
end

# app/serializers/hash_serializer.rb
class HashSerializer
  def self.dump(hash)
    hash
  end

  def self.load(hash)
    (hash || {}).with_indifferent_access
  end
end

Full credit - sans googling - goes to http://nandovieira.com/using-postgresql-and-jsonb-with-ruby-on-rails.




回答2:


If your root object is an array you need to handle it slightly differently.

Rails 5+

class User < ActiveRecord::Base
  serialize :preferences, HashSerializer
  serialize :some_list, ArrayHashSerializer
end

class HashSerializer
  def self.dump(hash)
    hash
  end

  def self.load(hash)
    (hash || {}).with_indifferent_access
  end
end

class ArrayHashSerializer
  def self.dump(array)
    array
  end

  def self.load(array)
    (array || []).map(&:with_indifferent_access)
  end
end

Rails <= 4

class User < ActiveRecord::Base
  serialize :preferences, HashSerializer
  serialize :some_list, ArrayHashSerializer
end

class HashSerializer
  def self.dump(hash)
    hash.to_json
  end

  def self.load(hash)
    (hash || {}).with_indifferent_access
  end
end

class ArrayHashSerializer
  def self.dump(array)
    array.to_json
  end

  def self.load(array)
    (array || []).map(&:with_indifferent_access)
  end
end


来源:https://stackoverflow.com/questions/28682428/is-there-a-way-to-serialize-activerecords-json-properties-using-hashwithindiffe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!