Jeff
Jeff

Reputation: 4423

Rails model -- non persistent class member or property?

Is it possible / advisable to have a member of a class that is not persisted to the database for a rails model?

I want to store the last type the user selects in a session variable. Since I cant set the session variable from my model, I want to store the value in a "dummy" class member that just passes the value back to the controller.

Can you have such a class member?

Upvotes: 5

Views: 2297

Answers (2)

max
max

Reputation: 102001

Adding non-persisted attributes to a Rails model is just like any other Ruby class:

class User < ActiveRecord::Base
   attr_accessor :someattr
end

me = User.new(name: 'Max', someattr: 'bar')
me.someattr  # "bar"
me.someattr = 'foo'

The extended explanation:

In Ruby all instance variables are private and do not need to be defined before assignment.

attr_accessor creates a setter and getter method:

class User < ActiveRecord::Base

   def someattr
     @someattr
   end

   def someattr=(value)
     @someattr = value
   end 
end

There is one special thing going on here; Rails takes the hash you pass to User.new and maps the values to attributes. You could simulate this behavior in a plain ruby class with something like:

class Foo

  attr_accessor :bar

  def initialize(hash)
    hash.keys.each do |key|
      setter = "#{key}=".intern
      self.send(setter, hash[key]) if self.respond_to? setter
    end
  end
end

> Foo.new(bar: 'baz')
=> <Foo:0x0000010112aa50 @bar="baz">

Classes in Ruby can also be re-opened at any point, ActiveRecord uses this ability to "auto-magically" add getters and setters to your models based on its database columns (ActiveRecord figures out which attributes to add based on the database schema).

Upvotes: 8

RoyTheBoy
RoyTheBoy

Reputation: 658

Yes you can, the code below allows you to set my_class_variable and inside the model reference it as @my_class_variable

class MyCLass < ActiveRecord::Base
  attr_accessor :my_class_variable

 def do_something_with_it
   @my_class_variable + 10
 end

Upvotes: 1

Related Questions