5

basically I have a user model that has an amount and money field. When I first create the user, I validate that user.amount <= user.money. However, the user is allowed to change the amount via 'edit'. In the update action, when the user changes the amount, I calculate the difference between the old and new (old minus new) amounts via

  amount_change = user.amount - params[:user][:amount].to_f

I don't know if this is good form but it works for me. Basically I'm not storing the difference and calculating it only as the user is trying to change the amount. Anyway when the user edits, I would like to validate that amount_change <= user.money instead. How can I do this? I feel like I should be passing something to the validation, but I don't know how I can pass in amount_change since it's calculated in the middle of the update method of my users controller. Thanks so much!

1 Answer 1

11

You can use ActiveModel::Dirty to access the old value (as amount_was):

class User < ActiveRecord::Base
  # ...
  validate :ensure_amount_change_less_than_money, 
           :on => :update, 
           :if => :amount_changed?

  def ensure_amount_change_less_than_money
    if (self.amount - self.amount_was) <= self.money
      errors.add(:money, 'Amount change must be less than money')
    end
  end
end
Sign up to request clarification or add additional context in comments.

4 Comments

this seems to sort of work--there's an error on the first attempt if it does not pass validation, but if the user just clicks submit again, there is no error...is this because a new amount_was and amount was set? thanks! (also is _changed built in?)
You can try removing :on => :update and see if that works better for you. _changed is built into ActiveModel and ActiveRecord.
hmm I can't get the _changed to work for some reason :/ I get a NoMethodError. Does it matter that my real amount variable is called start_amount? I did start_amount_changed?. Thanks!
That's strange. First, check to see if start_amount is in User.column_names (maybe there is an alias or something). Also check @user.changes and see if that gives a NoMethodError .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.