Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add new attribute to ActiveRecord

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 rails does not allow me to add one. What should I add in its model class?

@test.all

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

error:

can't write unknown attribute `newatt'
like image 219
Ladiko Avatar asked Aug 25 '13 13:08

Ladiko


People also ask

How do you add attributes to a model?

In the model attribute, select an attribute for which you want to add a new attribute. Click the Add button next to the selected attribute.

What are rails attributes?

Defines an attribute with a type on this model. It will override the type of existing attributes if needed. This allows control over how values are converted to and from SQL when assigned to a model. It also changes the behavior of values passed to ActiveRecord::Base.

What does Update_attributes do?

user. This method used to be called update_attributes in Rails 3. It changes the attributes of the model, checks the validations, and updates the record in the database if it validates. Note that just like update_attribute this method also saves other changed attributes to the database.

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code.


2 Answers

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.

like image 51
CuriousMind Avatar answered Sep 30 '22 04:09

CuriousMind


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.

like image 27
Andrew Schwartz Avatar answered Sep 30 '22 04:09

Andrew Schwartz