简体   繁体   English

向Rails模型添加动态属性

[英]Adding dynamic attributes to a Rails model

In earlier versions of Rails it was possible to add dynamic attributes to a model without the need for there to be an SQL column. 在早期版本的Rails中,可以将动态属性添加到模型中,而无需使用SQL列。 The following code worked pre 4.0. 以下代码在4.0之前有效。

drow = dtab1.drows.create()
drow.write_attribute('value1', 'xxx')
drow.write_attribute('value2', 'yyy')
drow.write_attribute('value3', 'zzz')

But now in v5 I get: 但是现在在v5中,我得到:

ActiveModel::MissingAttributeError: can't write unknown attribute `value1`

Is there any way to do that now? 现在有什么办法吗?

Other answers have proposed predefined accessors or replacing the dynamic fields by a "user variables" hash, but that won't work for my situation. 其他答案提出了预定义的访问器或将动态字段替换为“用户变量”哈希,但这对我的情况不起作用。 They need to be truly dynamic, created at runtime and treated as part of the model. 它们需要真正地动态,在运行时创建并被视为模型的一部分。

The write_attribute method updates the attribute in the underlying table. write_attribute方法更新基础表中的属性。 Since your new attributes are dynamic and do not match fields from your model table, no wonder it does not work. 由于您的新属性是动态的,并且与模型表中的字段不匹配,因此难怪它不起作用。

To add attribute dynamically you need to declare it first, and then to call setter as for regular attribute. 要动态添加属性,您需要先声明它,然后像常规属性一样调用setter。 For example: 例如:

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

The property will be saved to the instance variable @value1 . 该属性将保存到实例变量@value1

The other way to save dynamic property is to alter that variable directly, without declaring attribute accessor: 保存动态属性的另一种方法是直接更改该变量,而无需声明属性访问器:

drow.instance_variable_set("@#{attr_name}".to_sym, 'xxx') # setter
drow.instance_variable_get("@#{attr_name}".to_sym)        # getter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM