向 Rails 模型添加动态属性

dav*_*pfx 1 attributes ruby-on-rails

在 Rails 的早期版本中,可以向模型添加动态属性,而无需 SQL 列。以下代码在 4.0 之前有效。

drow = dtab1.drows.create()
drow.write_attribute('value1', 'xxx')
drow.write_attribute('value2', 'yyy')
drow.write_attribute('value3', 'zzz')
Run Code Online (Sandbox Code Playgroud)

但现在在 v5 中我得到:

ActiveModel::MissingAttributeError: can't write unknown attribute `value1`
Run Code Online (Sandbox Code Playgroud)

现在有什么办法可以做到吗?

其他答案提出了预定义的访问器或用“用户变量”哈希替换动态字段,但这不适用于我的情况。它们需要真正动态、在运行时创建并被视为模型的一部分。

Ily*_*hov 5

write_attribute方法更新基础表中属性。由于您的新属性是动态的并且与模型表中的字段不匹配,难怪它不起作用。

要动态添加属性,您需要首先声明它,然后像常规属性一样调用 setter。例如:

attr_name = 'value1'

# Declaring attr_accessor: attr_name
drow.instance_eval { class << self; self end }.send(:attr_accessor, attr_name)

drow.send(attr_name + '=', 'xxx')   # setter
drow.send(attr_name)                # getter
Run Code Online (Sandbox Code Playgroud)

该属性将被保存到实例变量中@value1

保存动态属性的另一种方法是直接更改该变量,而不声明属性访问器:

drow.instance_variable_set("@#{attr_name}".to_sym, 'xxx') # setter
drow.instance_variable_get("@#{attr_name}".to_sym)        # getter
Run Code Online (Sandbox Code Playgroud)