railslearner
railslearner

Reputation: 1821

Rails Validates Prevents Save

I have a user model like this:

class User < ActiveRecord::Base
    validates :password, :presence => true,
                         :confirmation => true,
                         :length => { :within => 6..40 }
    .
    .
    .
end

In the User model, I have a billing_id column I want to save into from a OrdersController which looks like this:

class OrdersController < ApplicationController
    .
    .
    .
    def create
        @order = Order.new(params[:order])
        if @order.save
            if @order.purchase
                response = GATEWAY.store(credit_card, options)
                result = response.params['billingid']
                @thisuser = User.find(current_user)
                @thisuser.billing_id  = result
                if @thisuser.save
                        redirect_to(root_url), :notice => 'billing id saved')
                    else
                        redirect_to(root_url), :notice => @thisuser.errors)
                    end
            end
        end
    end

Because of validates :password in the User model, @thisuser.save doesn't save. However, once I comment out the validation, @thisuser.save returns true. This is an unfamiliar territory for me because I thought this validation only worked when creating a new User. Can someone tell me if validates :password is supposed to kick in each time I try to save in User model? Thanks

Upvotes: 4

Views: 2293

Answers (2)

tadman
tadman

Reputation: 211580

You need to specify when you want to run your validations otherwise they will be run on every save call. This is easy to limit, though:

validates :password,
  :presence => true,
  :confirmation => true,
  :length => { :within => 6..40 },
  :on => :create

An alternative is to have this validation trigger conditionally:

validates :password,
  :presence => true,
  :confirmation => true,
  :length => { :within => 6..40 },
  :if => :password_required?

You define a method that indicates if a password is required before this model can be considered valid:

class User < ActiveRecord::Base
  def password_required?
    # Validation required if this is a new record or the password is being
    # updated.
    self.new_record? or self.password?
  end
end

Upvotes: 13

Jesse Wolgamott
Jesse Wolgamott

Reputation: 40277

It's likely because you are validating that the password has been confirmed (:confirmation => true), but the password_confirmation does not exist.

You can break this out to something like:

validates_presence_of :password, :length => { :within => 6..40 }
validates_presence_of :password_confirmation, :if => :password_changed?

I like this approach because if the user ever changes their password, it will require the user entered the same password_confirmation.

Upvotes: 0

Related Questions