Ruby-on-rails 使用 Rails 序列化将哈希保存到数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6694432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Rails serialize to save hash to database
提问by cmwright
I'm try to save a hash mapping ids to a number of attempts in my rails app. My migration to the database to accommodate this new column:
我正在尝试将哈希映射 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
In my model I have:
在我的模型中,我有:
class User < ActiveRecord::Base
serialize :multi_wrong, Hash
end
But when I use the rails console to test this by doing:
但是当我使用 rails 控制台通过执行以下操作来测试时:
user = User.create()
user.multi_wrong = {"test"=>"123"}
user.save
The output is false. What's going wrong here?
输出为假。这里出了什么问题?
回答by Benjamin Tan Wei Hao
The column type is wrong. You should use Text instead of String. Therefore, your migration should be:
列类型错误。您应该使用文本而不是字符串。因此,您的迁移应该是:
def self.up
add_column :users, :multi_wrong, :text
end
Then Rails will properly convert it into YAML for you (and perform proper serialization). Strings fields are limited in size and will only hold especially-small values.
然后 Rails 会为您正确地将其转换为 YAML(并执行正确的序列化)。字符串字段的大小有限,只能保存特别小的值。
回答by Blair Anderson
UPDATED:
更新:
Exact implementation will depend on your database, but PostgreSQL now has jsonand jsonbcolumns which can natively store your hash/object data and allow you to query against the JSON with ActiveRecord!
确切的实现将取决于您的数据库,但 PostgreSQL 现在具有json和jsonb列,可以本机存储您的哈希/对象数据,并允许您使用 ActiveRecord 查询 JSON!
change your migration and you're done.
改变你的迁移,你就完成了。
class Migration0001
def change
add_column :users, :location_data, :json, default: {}
end
end
ORIGINAL:
原来的:
For more details: rails docs&& apidock
有关更多详细信息:rails docs&& apidock
Make sure your column is :textand not :string
确保您的列是:text而不是:string
Migration:
移民:
$ rails g migration add_location_data_to_users location_data:text
$ rails g migration add_location_data_to_users location_data:text
should create:
应该创建:
class Migration0001
def change
add_column :users, :location_data, :text
end
end
Your Class Would Look Like:
你的班级看起来像:
class User < ActiveRecord::Base
serialize :location_data
end
Available Actions:
可用操作:
b = User.new
b.location_data = [1,2,{foot: 3, bart: "noodles"}]
b.save
More Awesome?!
更厉害?!
utilize postgresql hstore
使用 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
With hstore you can set attributes on the serialized field
使用 hstore,您可以在序列化字段上设置属性
class User < ActiveRecord::Base
# setup hstore
store_accessor :location_data, :city, :state
end
回答by Aboozar Rajabi
Rails 4 has a new feature called Store, so you can easily use it to solve your problem. You can define an accessor for it and it is recommended you declare the database column used for the serialized store as a text, so there's plenty of room. The original example:
Rails 4 有一个名为Store的新功能,因此您可以轻松地使用它来解决您的问题。您可以为它定义一个访问器,建议您将用于序列化存储的数据库列声明为文本,以便有足够的空间。原始示例:
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'

