Set attribute without database for rails model without `attr_accessor`

In PHP, I can set an attribute (which is not a column in the database) for the model. For example (PHP code),

$user = new User; $user->flag = true; 

But in rails, when I set any attribute that does not exist in the database, it will throw an undefined method flag error. There is an attr_accessor method, but what happens if I need about ten temporary attributes?

+9
source share
5 answers

This is expected because this is how ActiveRecord works on the project. If you need to set arbitrary attributes, you will have to use objects of a different type.

For example, Ruby provides a library called OpenStruct that allows you to create objects in which you can assign arbitrary keys / values. You might want to use such a library and then convert the object to the corresponding ActiveRecord instance only if / when you need to save it to the database.

Do not try to model ActiveRecord so that it behaves the way you just described, because it just was not designed to behave that way. This would be a cargo theft mistake from your current knowledge of PHP.

+6
source

but what happens if i need about ten temp attributes?

 #app/models/user.rb class User < ActiveRecord::Base attr_accessor :flag, :other_attribute, :other_attribute2, :etc... end 

attr_accessor creates "virtual" attributes in Rails - they do not exist in the database, but are present in the model.

As in the attributes from db, attr_accessor simply creates a set of setter and getter (instance) methods in your class that you can call and interact with when initializing the class:

 #app/models/user.rb class User < ActiveRecord::Base attr_accessor :flag # getter def flag @flag end # setter def flag=(val) @flag = val end end 
+10
source

As the guys explained, attr_accessor is just setter and getter .

We can set our attr_accessor model to initialize the record as Ruby # Hash , for example, using the ActiveRecord # After_initilize method , so we get more flexibility when storing values ​​temporarily ( credit idea for this answer ).

Sort of:

 class User < ActiveRecord::Base attr_accessor :vars after_initialize do |user| self.vars = Hash.new end end 

Now you can do:

 user = User.new #set user.vars['flag'] = true #get user.vars['flag'] #> true 
+3
source

All that attr_accessor does is add getter and setter methods that use the instance variable, like this

 attr_accessor :flag 

will add the following methods:

 def flag @flag end def flag=(val) @flag = val end 

You can write these methods yourself if you want, and ask them to do something more interesting than just storing the value in the var instance if you want.

+1
source

If you need temporary attributes, you can add them to a singleton object.

 instance = Model.new class << instance attr_accessor :name end 
0
source

All Articles