How to add a new attribute in ActiveRecord

After getting all the values ​​from the model, I want to add another custom attribute to the ActiveRecord class (this attribute is not a column in db), so I could use it in the field of view, but the rails do not allow adding it. What should be added to the model class?

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

Error:

 can't write unknown attribute `newatt' 
+6
source share
7 answers

try it

 class Test < ActiveRecord::Base attr_accessor :newattr end 

you can access it, for example

 @test = Test.new @test.newattr = "value" 

As you can see, this property is not a hash. therefore it uses syntax . . however, if you want it to behave like a hash, you can do this without defining a new attribute

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

Finally, I'm not quite sure what you are trying to do. if that doesn't make sense to you, kindly rephrase your question so that we can better understand the problem.

+8
source

Define virtual attributes as instance variables:

 attr_accessor :newattr 
+4
source

If you want this only for your views and do not have any other goals, you do not need to add attr_accessor

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

here you add the newattr attribute to output an ActiveRecord request with the value "added row"

+3
source

I think you want to assign @test to an ActiveRecord request, right? Try:

 @test = MyARClass.select("*, NULL as newatt") @test.each {|t| t[:newatt] = some_value} 

Another related solution is to make it a singleton class method, although you have to jump though more hoops to make it writable, and I intuitively feel that this is likely to cause additional overhead

 @test = MyARClass.all @test.each do t def t.newatt some_value end end 

Using the second method, of course, you will access it through @ test.first.newatt, and not @ test.first [: newatt]. You can try to override t. [] And t. [] = But it starts to get really dirty.

+2
source

If it is really just temporary, it should not 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 .

+2
source
 @test.all @test.each do |elm| write_attribute(:newatt, "added string") end 
+1
source

I met the same problem. and successfully get around with instance_eval

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

it usually does not start when attr_accessor is used. it appears when other DSLs override "newattr =" which causes the problem. In my case, this is money-rails "monetize: newatt"

Explicit use of write_attribute does not work, as this causes an exception to be raised in rails 4.x

0
source

Source: https://habr.com/ru/post/952454/


All Articles