Where to put this logic: model or controller?

I have an ActiveRecord model called User, here's my migration and model:

class CreateUsers < ActiveRecord::Migration   def self.up     create_table :users do |t|       t.column :email, :string, :null => false       t.column :full_name, :string, :null => false     end   end

  def self.down     drop_table :users   end end

To achieve this:

user=User.find(1); user.status => "ready"

You should a method in the model. Then you can access this method anywhere you have a User object. If you put it in the controller, you will have to repeat yourself everytime you want User.status

In your model:

def status "read" if.... etc. end

In your controller

def show    @user=User.find(1)   #your show view can now read the status method end

HTH

Here's my user model with the status logic:

class User < ActiveRecord::Base   attr :status, true

  def eval_status # this needs to be called anytime User is set     @status="Ready"   end end

So now how do I have eval_status called anytime I call User.find..?

With status now implimented in the model, when I call:

u=User.find(1)

u.status

=> nil

status isn't set so it's null. I need eval_status to be called somehow.

Any idea?

Why don't you just have the status method return what you need?

class User   def status     "Ready"   end end

Pat

This does the trick:

def evaluate_status     'Waiting'   end

  def status     @status ||= evaluate_status   end

put your initialization code into an after_initialize method, then it'll be called both when returning a user via User.new or User.find.

Also, I know you don't want to store your status or state in the database, but I just thought I'd mention the acts_as_state_machine plugin since it may be of some use to you (http://rails.aizatto.com/category/plugins/acts_as_state_machine/)

Adam

No… do not use after_initialize if you can avoid it. There are huge performance penalties, as in… it will be called any time you do a .new, or each time you create an instance. A finder that gets 50 records will call this code 50 times, and you can’t turn it off. If you look at the rails source, you’ll see comments basically warning you not to use after_initialize and after_find.

The best approach is to override the accessor as eggie5 suggested:

def evaluate_status ‘Waiting’ end

def status @status ||= evaluate_status end

Thanks for you help everyone. I remember seeing something like this in my rails book. It works great now just using the accessor like this:

def status       @status ||= eval_status # eval_status does the work to return the status   end

I just didn't know that ruby would automatically call it. So it just boils down to my ignorance of ruby.

thanks for the heads up Brian, I wasn't aware of the performance penalty that after_initialize might incur.

Adam