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
Define virtual attributes as instance variables:
attr_accessor :newattr
If you want this only for your views and do not have any other purpose then you need not to add 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'
I think you mean to assign @test to the ActiveRecord query, correct? 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, 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.
If it temporary, you can try this:
@test.all.map{ |t| t.attributes.merge({ newatt: "added string" }) }
I met the same issue. and successfully bypass using 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"
Explicitly use write_attribute doesn't work as it is the reason to raise exception in rails 4.x
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.