Validating required fields during an update?

I have a User model with an email attribute. I’m using the following
validations:

validates_confirmation_of :email

validates_format_of :email,
:with => RFC822::EmailAddress,
:message => “must be a valid address in the form [email protected]

validates_uniqueness_of :email, :message => “address has already
been taken. If you’ve forgotten your password, please click <a
href=“forgot_password”>here to reset it.”

validates_presence_of :email, :message => “address cannot be blank.”

This all works fine when a user is entering their information into the
signup form for the first time, however, the problem is when I’m
displaying an edit form to allow the user to change their details.

My client has asked that the user edit details form show the following
fields:

New Email: _____________
Confirm Email: _____________

so rather than show the current email address, the client wants both
of these boxes to be blank.

The problem is that if the user doesn’t enter a new email address, the
validations will fire, the object will be marked as invalid (since the
email address is blank) and any of the other options that may have
been changed will not be saved. So I need to figure out how to avoid
running the email validations if the user hasn’t entered a value for
new email. If anyone has any suggestions, please let me know.
Thanks,

Mike

To leave the field blank, add

:value => nil

In your form tag helper.

For the second part, you’ll need a conditional code block to apply the
validation selectively.

validates_confirmation_of :email,
:if => Proc.new { |user| user.email !nil }

I might be messing the block up, but you get the idea. Can’t run it at
the moment to test.

Hope that helps,

Jim

i’m pretty new myself so i don’t know if this is the correct or most
elegant way to solve it, but i’ve used something like this in my own
work:

attr_accessor :new_email

validates_confirmation_of :email,
:on => :create
validates_confirmation_of :new_email,
:on => :update,
:if => :has_new_email

validates_format_of :email,
:with => RFC822::EmailAddress,
:message => “must be a valid address in the form [email protected]”,
:on => :create
validates_format_of :new_email,
:with => RFC822::EmailAddress,
:message => “must be a valid address in the form [email protected]”,
:on => :update,
:if => :has_new_email

validates_uniqueness_of :email, :message => “address has already
been taken. If you’ve forgotten your password, please click <a
href=“forgot_password”>here to reset it.”,
:on => :create
validates_uniqueness_of :new_email, :message => “address has already
been taken. If you’ve forgotten your password, please click <a
href=“forgot_password”>here to reset it.”,
:on => :update,
:if => :has_new_email

validates_presence_of :email,
:message => “address cannot be blank.”,
:on => :create
validates_presence_of :email,
:message => “address cannot be blank.”,
:on => :update,
:if => :has_new_email

protected
def has_new_email
return (self.new_email.length > 0)
end

On 8/14/06, Jim L. [email protected] wrote:

To leave the field blank, add

:value => nil
In your form tag helper.

this didn’t actually work for me… I had to use :value => “” in order
to get it to set a blank value… I ended up just using:

text_field_tag ‘user[email]’

instead

On 8/14/06, jeff emminger [email protected] wrote:

i’m pretty new myself so i don’t know if this is the correct or most
elegant way to solve it, but i’ve used something like this in my own
work:

    return (self.new_email.length > 0)

end

thanks for the suggestions guys. I like your idea Jeff, but I ended up
using the
following to avoid duplicating each of my validation requirements:

user.rb:

validates_confirmation_of :email, :if => :email_changed?

validates_format_of :email,
:with => RFC822::EmailAddress,
:message => " must be a valid address in the form [email protected]"

validates_uniqueness_of :email, :message => “address has already
been taken. If you’ve forgotten your password, please click <a
href="forgot_password">here to reset it.”

we want the following to only activate when initially creating a

User object
validates_presence_of :email, :message => “address cannot be
blank.”, :on => :create

detects whether the email address passed in the form

is different from the current email address of the user

def email_changed?
begin
email != User.find(id).email
rescue
end
end

prevents setting an empty email

def email=(new_email)
super unless new_email.blank?
end

it seems to work fine - hopefully I haven’t missed anything in my
logic…