如何向ActiveRecord添加新属性

从模型中获取所有值后,我想向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 :newattr 

如果您只想将此视图用于视图而没有任何其他目的,则无需添加attr_accessor

 @test.all.select('tests.*, "added string" as newattr') 

在这里,您要为ActiveRecord的查询输出添加newattr属性,其值为’added string’

我认为你的意思是将@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 @test.each do |elm| write_attribute(:newatt, "added string") end 

我遇到了同样的问题。 并成功绕过使用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中引发exception的原因

如果是临时的,你可以试试这个:

@test.all.map{ |t| t.attributes.merge({ newatt: "added string" }) }