在我的rails模型中,我有一个存储一些元信息的JSON列。 这将从表单输入用户。
由于JSON列的键不是模型的属性,我不能直接在form_for
中使用它们,而是需要定义一个虚拟属性。
由于这个虚拟属性的数量可能会增长到任意长度,我想使用元编程来定义属性。
我确实在this question中尝试了答案但是当我在模型中使用常量时,我得到一个错误,说明常量是未定义的。所以我直接在数组中添加了键的符号,并在模块中迭代它们。当我这样做时,我得到一个错误,表示堆栈级别太深。
有人可以帮助我吗?
答案 0 :(得分:2)
我明白了。我将该属性作为JSON列的键返回,现在它可以正常工作。
# lib/virtuals.rb
module Virtuals
%W(key_1 key_2 key_3).each do |attr|
define_method(attr) do
self.my_json_column[attr]
end
define_method("#{attr}=") do |val|
self.my_json_column[attr] = val
end
end
end
在我的模型中,我只需要包含上面的模块,它在form_for
中工作正常,并且也可以正确更新。
答案 1 :(得分:2)
如果您使用PostgreSQL
特定列,例如hstore
或json
,只需使用store_accessor
来生成访问者方法。 请注意,这些列使用字符串键控哈希,并且不允许使用符号进行访问。
class Model < ActiveRecord::Base
store_accessor :my_json_column, [ :key_1, :key_2, key_3 ]
end
引擎盖下做什么?它定义了write \ read辅助方法:
def store_accessor(store_attribute, *keys)
keys = keys.flatten
_store_accessors_module.module_eval do
keys.each do |key|
define_method("#{key}=") do |value|
write_store_attribute(store_attribute, key, value)
end
define_method(key) do
read_store_attribute(store_attribute, key)
end
end
end
#.....