Ruby-on-rails 如何向 ActiveRecord 添加新属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18429274/
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
How to add new attribute to ActiveRecord
提问by Ladiko
After getting all values from model, I want to add another custom attribute to the ActiveRecord class (this attribute is not a column in db) so that I could use it in view, but rails does not allow me to add one. What should I add in its model class?
从模型中获取所有值后,我想向 ActiveRecord 类添加另一个自定义属性(此属性不是 db 中的列),以便我可以在视图中使用它,但 Rails 不允许我添加一个。我应该在它的模型类中添加什么?
@test.all
@test.each do |elm|
elm[:newatt] = 'added string'
end
error:
错误:
can't write unknown attribute `newatt'
回答by CuriousMind
try this
尝试这个
class Test < ActiveRecord::Base
attr_accessor :newattr
end
you can access it like
你可以像这样访问它
@test = Test.new
@test.newattr = "value"
As you may notice this a property, not a hash. so it uses .syntax. however, if you need it to behave like an hash you can do this without defining a new attribute
您可能会注意到这是一个属性,而不是哈希。所以它使用.语法。但是,如果您需要它表现得像一个散列,您可以在不定义新属性的情况下执行此操作
@test.all
@test.each do |elm|
new_elm = {}
new_elm[:newatt] = 'added string'
end
Lastly, I am not exactly sure what you are trying to do. if this doesn't make sense to you, kindly rephrase your question so we can understand the problem better.
最后,我不确定您要做什么。如果这对您没有意义,请重新表述您的问题,以便我们更好地理解问题。
回答by sajith
If you want this only for your views and do not have any other purpose then you need not to add attr_accessor
如果您只希望这仅用于您的视图并且没有任何其他目的,那么您无需添加 attr_accessor
@test.all.select('tests.*, "added string" as newattr')
here you are adding newattr attribute for query output of ActiveRecord with a value 'added string'
在这里,您正在为 ActiveRecord 的查询输出添加 newattr 属性,其值为“已添加字符串”
回答by boulder
Define virtual attributes as instance variables:
将虚拟属性定义为实例变量:
attr_accessor :newattr
回答by Andrew Schwartz
I think you mean to assign @test to the ActiveRecord query, correct? Try:
我认为您的意思是将 @test 分配给 ActiveRecord 查询,对吗?尝试:
@test = MyARClass.select("*, NULL as newatt")
@test.each {|t| t[:newatt] = some_value}
Another related solution is to make it a singleton class method, though you'd have to jump though more hoops to make it writeable and I intuitively feel like this probably incurs more overhead
另一个相关的解决方案是使它成为一个单例类方法,尽管你必须跳过更多的箍以使其可写,我直觉地觉得这可能会导致更多的开销
@test = MyARClass.all
@test.each do t
def t.newatt
some_value
end
end
Using the second method, of course you'd access it via @test.first.newatt, rather than @test.first[:newatt]. You could try redefining t.[] and t.[]=, but this is starting to get really messy.
使用第二种方法,当然你会通过@test.first.newatt 访问它,而不是@test.first[:newatt]。您可以尝试重新定义 t.[] 和 t.[]=,但这开始变得非常混乱。
回答by Chris Kerlin
If it's really just temporary it doesn't have to be in the object:
如果它真的只是暂时的,它不必在对象中:
@test.all
@test_temp = []
@test.each do |elm|
@test_temp << {:elm => elm, :newatt => 'added string'}
end
Otherwise, there are also good answers here.
否则,这里也有很好的答案。
回答by Hugo
@test.all
@test.each do |elm|
write_attribute(:newatt, "added string")
end
回答by Gundam Meister
If it temporary, you can try this:
如果是暂时的,你可以试试这个:
@test.all.map{ |t| t.attributes.merge({ newatt: "added string" }) }
@test.all.map{ |t| t.attributes.merge({ newatt: "added string" }) }
回答by roadtang
I met the same issue. and successfully bypass using instance_eval
我遇到了同样的问题。并使用 instance_eval 成功绕过
@test.all
@test.each do |elm|
elm.instance_eval { @newatt = 'added string' }
end
normally it doesn't run into issue, when use attr_accessor. it appears when other DSL override "newattr=" which cause the issue. In my case, it's money-rails "monetize :newatt"
通常它不会遇到问题,当使用 attr_accessor 时。当其他 DSL 覆盖导致问题的“newattr=”时,它就会出现。就我而言,它是货币轨“货币化:newatt”
Explicitly use write_attribute doesn't work as it is the reason to raise exception in rails 4.x
显式使用 write_attribute 不起作用,因为它是在 rails 4.x 中引发异常的原因

