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

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

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 控制台通过以下方法来测试这一点:

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

输出是假的,这里出了什么问题?

102046 次浏览

列类型错误。您应该使用 Text 而不是 String。因此,您的迁移应该是:

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

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

UPDATED:

确切的实现将取决于您的数据库,但 PostgreSQL 现在有 jsonjsonb列,它们可以本地存储您的散列/对象数据,并允许您使用 使用 ActiveRecord 对 JSON 进行查询

改变你的迁移,你就完了。

class Migration0001
def change
add_column :users, :location_data, :json, default: {}
end
end

原创:

更多细节: < a href = “ http://api.rubyonRails.org/classes/ActiveRecord/Base.html # class-ActiveRecord: : Base-label-Save + array-2C + hash-2C + and + other + non-mapable + object + in + text + column”rel = “ noReferrer”> Railsdocs & & 一个 href = “ http://apidock.com/ails/ActiveRecord/AttributeMethod/Serialization/ClassMethod/Series alize”rel = “ noReferrer”> apidock

确保你的专栏是 :text而不是 :string

移民:

$ rails g migration add_location_data_to_users location_data:text

应创造:

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

更棒? !

利用后处理软件

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

Rails4有一个新的特性叫做 商店,所以你可以很容易地使用它来解决你的问题。您可以为它定义一个访问器,建议您将用于序列化存储的数据库列声明为文本,这样就有足够的空间。最初的例子是:

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'