ryanpitts1
ryanpitts1

Reputation: 894

Rails 3 - How to change attribute in controller before update save?

So, i have form that updates a record in the database. In my controllers update action i want to change a value to something if another one of the values is Estimate. Maybe this will make more sense...this is what i'm trying to do.

def update
    @invoice = Invoice.find(params[:id])
    if @invoice.update_attributes(params[:invoice])
        [email protected] == "Estimate"
            # if the value of status is Estimate then change the
            # value of estimate_sent_date to the current timestamp
        end
        redirect_to invoices_path
    else
        render 'edit'
    end
end

The only values of the form that i'm concerned with are status and estimate_sent_date. Mostly, i'm just not sure how to change the value of estimate_sent_date and save that record.

Also, should i save everything and then do a separate call to save the estimate_sent_date or just save it all at once? I guess i could change the value of estimate_sent_date before calling if @invoice.update_attributes(params[:invoice]), couldn't i?

Thanks for the help!

Upvotes: 0

Views: 7927

Answers (3)

Ryan Bigg
Ryan Bigg

Reputation: 107708

It sounds like you're trying to re-invent a state machine here. I would recommend looking into the state_machine gem and then using it to implement an event that happens after an invoice transitions to the 'estimate' state, placing this inside the state_machine definition which would go inside your model:

after_transition :to => :estimate do |invoice|
  invoice.estimate_sent_date = Time.now
end

Upvotes: 1

jeremiemv
jeremiemv

Reputation: 138

I would move this kind of business logic in your Invoice model. This is a typical use case for a :before_save callback

Upvotes: 2

aguynamedloren
aguynamedloren

Reputation: 2273

As Ryan Bigg says, state machine does work here. An alternative solution is to use a before_save callback on the Invoice model, like so:

before_save :set_sent_date

def set_sent_date
  if self.status_changed? && self.status == "Estimate"
     self.estimate_sent_date = Time.now
  end
end

Upvotes: 5

Related Questions