如何向ActiveRecord添加新属性

时间:2013-08-25 13:01:54

标签: ruby-on-rails

从模型中获取所有值后,我想向ActiveRecord类添加另一个自定义属性(此属性不是db中的列),以便我可以在视图中使用它,但rails不允许我添加一个。我应该在其模型类中添加什么?

@test.all

@test.each do |elm|
    elm[:newatt] = 'added string'
end

错误:

can't write unknown attribute `newatt'

8 个答案:

答案 0 :(得分:10)

试试这个

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

最后,我不确定你要做什么。如果这对你没有意义,请仔细改写你的问题,这样我们就能更好地理解这个问题。

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:4)

将虚拟属性定义为实例变量:

attr_accessor :newattr

答案 3 :(得分:2)

我认为您的意思是将@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。[] =,但这开始变得非常混乱。

答案 4 :(得分:2)

如果它真的只是暂时的,它不必在对象中:

@test.all
@test_temp = []

@test.each do |elm|
    @test_temp << {:elm => elm, :newatt => 'added string'}
end   

否则,还有good answers here

答案 5 :(得分:1)

@test.all

@test.each do |elm|
    write_attribute(:newatt, "added string")
end

答案 6 :(得分:1)

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

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

答案 7 :(得分:0)

我遇到了同样的问题。并成功绕过使用instance_eval

@test.all

@test.each do |elm|
  elm.instance_eval { @newatt = 'added string' }
end

通常在使用attr_accessor时不会遇到问题。当其他DSL覆盖&#34; newattr =&#34;这导致了这个问题。在我的情况下,它是金钱轨道&#34;货币化:newatt&#34;

显式使用write_attribute并不起作用,因为它是在rails 4.x中引发异常的原因