绕过rails提供的数据存储的东西,我有一些困扰我的东西
假设我有一个简单的帖子模型,带有title
,并且出于某种原因,我想以某种方式将动态属性存储在另一个字段中,称为" post_garbage
在后期模型中,我有简单的序列化程序:
class Post < ActiveRecord::Base
serialize :post_garbage
end
正如我所说,除了 rails 文档解释的内容外,在此post_garbage
字段中没有设置命名访问器
在控制台中播放:
p = Post.first
p.post_garbage["the_stuff"] = "something"
p.save
显然,我得到了一个错误。"the_stuff"未知。停在这里,你想转储这个data_store的东西,更安全,更容易创建一个新字段来完成工作(如果你必须在data_store字段上设置访问器,我不明白它的实用性)。
*但*
如果首先在此post_garbage
字段中保存一个空哈希:
p = Post.first
p.post_garbage = {}
p.save
以下情况成为可能:
p = Post.first
p.post_garbage["whatever_i_have_in_mind"] = "some value"
p.save
紧接着:
p.post_garbage["it_then_get_dynamic"] = "and that's pretty cool"
p.save
它变得无模式,不需要指定访问器;有点提供预期的东西。所以我想知道:许多人会期望数据存储有一个无模式的东西,但文档并没有这样使用它。但它有效,看起来像一个糟糕的把戏。奇迹。。。
相反,serialize :post_garbage
有什么用,如果当为空时,它不返回空哈希?
真的很感激对此的一些经验丰富的反馈,因为我觉得我错过了一些东西
多谢
这可能与对象初始化时p.post_garbage中没有值的事实有关。
p.post_garbage["the_stuff"] = "something"
试图隐式地将post_garbage视为哈希。最终将类似于
unset_variable = nil
unset_variable['hash_key'] = 'hash_value'
对属性使用序列化方法告诉 Rails 它应该期望将对象压缩为键值映射,并将其作为文本存储在数据库中。但这并不一定意味着您的对象是将其实例化为哈希的。它可以是任何特定的对象。但是,需要先将该对象分配给属性,然后才能对其进行序列化。序列化可能会解决在加载时存储和重构它的魔术,但如果未初始化,它不会对该对象的形式做出任何假设。因此,在没有任何指示的情况下,Ruby post_garbage不会期望它是一个哈希。
至于为什么空的时候不返回空的有? 空对象和缺失对象之间存在差异。(即:{} vs nil)。它们不是一回事,通常丢失的对象被视为空对象。但是这种区别是有价值的,我希望 Rails 在加载序列化属性时会保留它。
也许您应该尝试在创建时使用这样的东西初始化它?
class Post < ActiveRecord::Base
serialize :post_garbage
after_initialize :default_values
private
def default_values
self.post_garbage ||= {}
end
end