使用Rails序列化将散列保存到数据库

我试着在我的Rails应用程序中保存一个哈希映射ID到一些尝试。 我迁移到数据库以适应这个新列:

class AddMultiWrongToUser < ActiveRecord::Migration def self.up add_column :users, :multi_wrong, :string end def self.down remove_column :users, :multi_wrong end end 

在我的模型中,我有:

 class User < ActiveRecord::Base serialize :multi_wrong, Hash end 

但是当我使用rails控制台来做这个testing时:

 user = User.create() user.multi_wrong = {"test"=>"123"} user.save 

输出是错误的。 这里怎么了?

列types是错误的。 您应该使用文本而不是string。 因此,您的迁移应该是:

  def self.up add_column :users, :multi_wrong, :text end 

然后Rails会正确地将其转换为YAML(并执行正确的序列化)。 string字段的大小是有限的,只能保持特别小的值。

欲了解更多详情: 铁轨文件 && apidock

确保你的列是:text和not :string

移民:

$ rails g migration add_location_data_to_users location_data:text

应该创build:

 class Migration0001 def change add_column :users, :location_data, :text end end 

你的课堂看起来像:

 class User < ActiveRecord::Base serialize :location_data end 

可用操作:

 b = User.new b.location_data = [1,2,{foot: 3, bart: "noodles"}] b.save 

更多真棒?

利用postgresql hstore

 class AddHstore < ActiveRecord::Migration def up enable_extension :hstore end def down disable_extension :hstore end end class Migration0001 def change add_column :users, :location_data, :hstore end end 

使用hstore,您可以在序列化字段上设置属性

 class User < ActiveRecord::Base # setup hstore store_accessor :location_data, :city, :state end 

Rails 4有一个名为Store的新function,所以你可以很容易的使用它来解决你的问题。 您可以为它定义一个访问器,build议您将用于序列化商店的数据库列作为文本声明,所以有足够的空间。 原来的例子:

 class User < ActiveRecord::Base store :settings, accessors: [ :color, :homepage ], coder: JSON end u = User.new(color: 'black', homepage: '37signals.com') u.color # Accessor stored attribute u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor # There is no difference between strings and symbols for accessing custom attributes u.settings[:country] # => 'Denmark' u.settings['country'] # => 'Denmark'