27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

80 CHAPTER 3 Developing a real Rails application<br />

The create! method, instead of nonchalantly handing back a Project object regardless<br />

of any validations, raises an ActiveRecord::RecordInvalid exception if any of the<br />

validations fail, showing the exception followed by a large stacktrace, which you can<br />

safely ignore for now. You are notified which validation failed. To stop it from failing,<br />

you must pass in a name attribute, and it will happily return a saved Project object:<br />

irb(main):002:0> Project.create!(:name => "TextMate 2")<br />

=> #<br />

That’s how to use create to test it in the console, but in your ProjectsController,<br />

you use the method shown in the following listing instead.<br />

Listing 3.29 app/controllers/projects_controller.rb<br />

@project = Project.new(params[:project])<br />

@project.save<br />

save doesn’t raise an exception if validations fail, as create! did, but instead returns<br />

false. If the validations pass, save returns true. You can use this to your advantage to<br />

show the user an error message when this returns false by using it in an if statement.<br />

Make the create action in the ProjectsController, as in the following listing.<br />

Listing 3.30 app/controllers/projects_controller.rb<br />

def create<br />

@project = Project.new(params[:project])<br />

if @project.save<br />

flash[:notice] = "Project has been created."<br />

redirect_to @project<br />

else<br />

flash[:alert] = "Project has not been created."<br />

render :action => "new"<br />

end<br />

end<br />

Now if the @project object is valid, then save returns true and executes everything<br />

between the if and the else. If it isn’t valid, then everything between the else and<br />

the following end is executed. In the else, you specify a different key for the flash message<br />

because you’ll want to style alert messages differently from notices later in the<br />

application’s lifecycle.<br />

When you run rake cucumber:ok here, the second step of your second scenario<br />

passes because you now have the flash[:alert] set:<br />

Then I should see "Project has not been created."<br />

And I should see "Name can't be blank"<br />

expected #has_content?("Name can't be blank")<br />

to return true, got false<br />

...<br />

12 steps (1 failed, 11 passed)

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!