Be_valid (validates_format_of ..., :on => :create)


#1

Greetings,

How to write Example which will check if model’s variable’s
format is valid using :on => :create, like this:

class User < ActiveRecord::Base

validates_format_of :email, :with => /…/, :on => :create

Using following code is not right:
it “should …” do
@user = users(:example_user)
@user.email = ‘invalid_email_format’
@user.save
@user.should_not be_valid
end

Even those code is not right:
it "should … " do
@user = users(:example_user)
@user.email = ‘invalid_email_format’
@user.save
@user.should be_valid
end

Thanks.


#2

On 28-feb-2009, at 11:45, MAwiniarski wrote:

Using following code is not right:
it “should …” do
@user = users(:example_user)
@user.email = ‘invalid_email_format’
@user.save
@user.should_not be_valid
end

Try:

it “should …” do
user = User.new # create a NEW user, instead of loading an
already saved user from a fixtures file
user.email = ‘invalid_email_format’
user.should_not be_valid
user.should have(1).errors_on(:email)
end

cheers,
bartz


#3

On 2-mrt-2009, at 16:50, David C. wrote:

class User < ActiveRecord::Base
end
end

+1

I might combine the first two lines:

user = User.create(:email => “invalid_email_format”)

That reads more clearly to me because the invalid email format is
assigned on create, not after. It would have an extra call to valid?
but I think it’s worth it for the clarity of intent in this case.

Although I agree with the reasoning you display here, I’d never
validate any attribute just on create.
I’m pretty sure a user can update his email address somewhere in the
site, but then his email address wouldn’t be validated anymore.

On a second note, I noticed rspec default generated model specs now
use Model.create!(@valid_attributes) as their default “all is valid”
test. What’s the advantage of this approach? I just write
@model.attributes = @valid_attributes; @model.should be_valid, to
prevent these specs to actually hit the db, and therefore speed up my
specs a bit.

thanks,
bartz


#4

On Mon, Mar 2, 2009 at 10:23 AM, Bart Z.
removed_email_address@domain.invalid wrote:

How to write Example which will check if model’s variable’s
@user.email = ‘invalid_email_format’
user.should_not be_valid
assigned on create, not after. It would have an extra call to valid?
but I think it’s worth it for the clarity of intent in this case.

Although I agree with the reasoning you display here, I’d never validate
any attribute just on create.
I’m pretty sure a user can update his email address somewhere in the site,
but then his email address wouldn’t be validated anymore.

FWIW, the OP’s code says :on => :create. I also happened to see
http://mawiniarski.wordpress.com/2009/02/28/rspec-validation-on-create/,
which reinforced for me that this is about validating on create, not
general validation.

On a second note, I noticed rspec default generated model specs now use
Model.create!(@valid_attributes) as their default “all is valid” test.
What’s the advantage of this approach? I just write @model.attributes =
@valid_attributes; @model.should be_valid, to prevent these specs to
actually hit the db, and therefore speed up my specs a bit.

Good point. Wanna submit a patch? http://rspec.lighthouseapp.com

Cheers,
David


#5

On Mon, Mar 2, 2009 at 8:20 AM, Bart Z. removed_email_address@domain.invalid
wrote:

validates_format_of :email, :with => /…/, :on => :create
Try:

it “should …” do
user = User.new # create a NEW user, instead of loading an already saved
user from a fixtures file
user.email = ‘invalid_email_format’
user.should_not be_valid
user.should have(1).errors_on(:email)
end

+1

I might combine the first two lines:

user = User.create(:email => “invalid_email_format”)

That reads more clearly to me because the invalid email format is
assigned on create, not after. It would have an extra call to valid?
but I think it’s worth it for the clarity of intent in this case.

Otherwise, this is the right idea, IMO.

Cheers,
David


#6

On Mon, Mar 2, 2009 at 8:23 AM, Bart Z. removed_email_address@domain.invalid
wrote:

On a second note, I noticed rspec default generated model specs now use
Model.create!(@valid_attributes) as their default “all is valid” test.
What’s the advantage of this approach? I just write @model.attributes =
@valid_attributes; @model.should be_valid, to prevent these specs to
actually hit the db, and therefore speed up my specs a bit.

Wouldn’t it be better to go through the complete create! cycle, to
make sure callbacks and database constraints (if any) are exercised?

///ark


#7

On 2-mrt-2009, at 18:12, Mark W. wrote:

actually hit the db, and therefore speed up my specs a bit.

Wouldn’t it be better to go through the complete create! cycle, to
make sure callbacks and database constraints (if any) are exercised?

Could be, but imagine I have 5 validations on my model. Only the
first will throw an error on create!.
And since my validations are in Dutch, I specifically test each
validation to see whether it returns the correct error message.

I use the following structure:

class Article
validates_presence_of :title
end

describe Article
before(:each) do
@article = Article.new
@valid_attributes = { :title => “Title” }
end

it “should not be valid without a title” do
@article.attributes = @valid_attributes.except :title
@article.should_not be_valid
end

it “should be valid with all valid attributes” do
@article.attributes = @valid_attributes
@article.should be_valid
end
end


#8

FWIW, the OP’s code says :on => :create. I also happened to seehttp://mawiniarski.wordpress.com/2009/02/28/rspec-validation-on-create/,
which reinforced for me that this is about validating on create, not
general validation.

I’ve figured that out after starting a topic.