views:

144

answers:

4

Hello fellow stackoverflow members.

I have been following this guide to enable users to have their own avatar.

But i have bumped in to a litle problem. When the user is cropping the image the model tries to validate all my validations. My user model looks like this:

class User < ActiveRecord::Base

  has_attached_file :avatar, :styles => { :small => "100x100>", :large => "500x500>" }, :processors => [:cropper]

  attr_accessor :password, :crop_x, :crop_y, :crop_w, :crop_h
  attr_accessible :crop_x, :crop_y, :crop_w, :crop_h
  validates_confirmation_of :password
  validates_presence_of :password

And when the user runs the crop updating script the user model tries to validate the password. But because i have no password field on the cropping page it can't validate it.

Here is the updating of the crop:

@user = User.find(current_user.id)
  if @user.update_attributes(params[:user])
    flash[:notice] = "Successfully updated user."
  end

How can i bypass this in a easy and clean way?

A: 

Try conditional validation:

validates_confirmation_of :password, :if => :password
validates_presence_of :password, :if => :password
Tony Fontenot
this is not really a good idea i think, this will caused problem in the original form where password is really required
Staelen
Not really. Because the if in this case checks for null. The only way for the password to be null is for it to be left off the form or the value is set to null in code. Either way it would be a programming and not a user validation. I agree it's a quick and dirty, but it's food for thought for the original poster.
Tony Fontenot
A: 

Based on the technique used by authlogic, try validating the password only when it's new record, the password has changed, or the crypted password (the column where you store the hashed/crypted password) is blank.

class User
  validates_confirmation_of :password, :if => :require_password?
  validates_presence_of :password, :if => :require_password?

  def password=(pass)
    return if pass.blank?

    # Encrypt password, etc
    # ...

    @password_changed = true
  end


  private
    def require_password?
      new_record? || @password_changed || crypted_password.blank?
    end
end
htanata
A: 

Similar answer to @htanata, but using ActiveRecord:Dirty:

class User
  validates_confirmation_of :password, :if => 'self.password_changed?'
  validates_presence_of :password, :if => 'self.password_changed?'
end
klew
Or `:if => :password_changed?` for brevity.
htanata
A: 

Call #save and pass it false to disable validations for that one database update.

Change your controller code to this:

@user = User.find(current_user.id)
@user.attributes = params[:user]
if @user.save(false)
    flash[:notice] = "Successfully updated user."
end

This would cause you problems if you were relying on Paperclip to do image validation. It might cover up some problems with badly formatted image files, but it's possibly worth the trade off.

Otto