从模型中获取所有值后,我想向 ActiveRecord 类添加另一个自定义属性(此属性不是 db 中的列),以便我可以在视图中使用它,但 rails 不允许我添加一个。我应该在它的模型类中添加什么?
@test.all
@test.each do |elm|
elm[:newatt] = 'added string'
end
错误:
can't write unknown attribute `newatt'
从模型中获取所有值后,我想向 ActiveRecord 类添加另一个自定义属性(此属性不是 db 中的列),以便我可以在视图中使用它,但 rails 不允许我添加一个。我应该在它的模型类中添加什么?
@test.all
@test.each do |elm|
elm[:newatt] = 'added string'
end
错误:
can't write unknown attribute `newatt'
尝试这个
class Test < ActiveRecord::Base
attr_accessor :newattr
end
你可以像访问它
@test = Test.new
@test.newattr = "value"
您可能会注意到这是一个属性,而不是哈希。所以它使用.
语法。但是,如果您需要它表现得像一个哈希,您可以在不定义新属性的情况下执行此操作
@test.all
@test.each do |elm|
new_elm = {}
new_elm[:newatt] = 'added string'
end
最后,我不确定您要做什么。如果这对您没有意义,请重新表述您的问题,以便我们更好地理解问题。
如果您只想将其用于您的视图并且没有任何其他目的,那么您无需添加 attr_accessor
@test.all.select('tests.*, "added string" as newattr')
在这里,您正在为 ActiveRecord 的查询输出添加 newattr 属性,其值为“添加的字符串”
将虚拟属性定义为实例变量:
attr_accessor :newattr
我认为您的意思是将 @test 分配给 ActiveRecord 查询,对吗?尝试:
@test = MyARClass.select("*, NULL as newatt")
@test.each {|t| t[:newatt] = some_value}
另一个相关的解决方案是使它成为一个单例类方法,尽管你必须跳更多的圈才能使它可写,我直觉上觉得这可能会产生更多的开销
@test = MyARClass.all
@test.each do t
def t.newatt
some_value
end
end
使用第二种方法,您当然可以通过@test.first.newatt 访问它,而不是@test.first[:newatt]。您可以尝试重新定义 t.[] 和 t.[]=,但这开始变得非常混乱。
如果它真的只是暂时的,则不必在对象中:
@test.all
@test_temp = []
@test.each do |elm|
@test_temp << {:elm => elm, :newatt => 'added string'}
end
否则,这里也有很好的答案。
如果是暂时的,你可以试试这个:
@test.all.map{ |t| t.attributes.merge({ newatt: "added string" }) }
我遇到了同样的问题。并使用 instance_eval 成功绕过
@test.all
@test.each do |elm|
elm.instance_eval { @newatt = 'added string' }
end
通常它不会遇到问题,当使用 attr_accessor 时。它出现在其他 DSL 覆盖导致问题的“newattr=”时。就我而言,这是金钱轨道“货币化:newatt”
显式使用 write_attribute 不起作用,因为它是在 rails 4.x 中引发异常的原因
@test.all
@test.each do |elm|
write_attribute(:newatt, "added string")
end