27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Prettying URLs<br />

of these invalid characters then it will be removed completely. By doing this, it makes<br />

the name safe to be used as a parameter in the URL, hence the name parameterize.<br />

Before you actually make this change, you’re going to write a test for it to make<br />

sure that this feature of your code isn’t accidentally changed or removed. Because this<br />

change is going to be for your Ticket model, you’re going to put the test for it in<br />

spec/models/ticket_spec.rb, using the code from the following listing:<br />

Listing B.1 spec/models/ticket_spec.rb<br />

require 'spec_helper'<br />

describe Ticket do<br />

it "has pretty URLs" do<br />

ticket = Factory(:ticket, :title = "Make it shiny!")<br />

ticket.to_param.should eql("#{ticket.id}-make-it-shiny")<br />

end<br />

end<br />

This code will use the factory you created in chapter 7 to create a new ticket with the<br />

title “Make it shiny!” Then you call to_param on that ticket, and you expect to see it<br />

output the ticket’s id followed by the parameterized version of “Make it shiny”: makeit-shiny.<br />

When you run this test with bin/rspec spec/models/ticket_spec.rb, you’ll see<br />

the following output:<br />

expected "1-make-it-shiny"<br />

got "1"<br />

This is happening because you haven’t yet overridden the to_param method in your<br />

Ticket model and it is defaulting to just providing the id. To fix this, you can open<br />

the app/models/ticket.rb and add in the new method:<br />

def to_param<br />

"#{id}-#{title.parameterize}"<br />

end<br />

When you run our test again, it will now be green:<br />

1 example, 0 failures<br />

You don’t have to change anything else because Rails is still so incredibly darn smart!<br />

For instance, you can pass this “1-make-it-shiny” string to the find method, and Rails<br />

will still know what to do. Go ahead, try this:<br />

Ticket.find("1-make-it-shiny")<br />

If you have a record in the tickets table with an id value of 1, Rails will find this. This<br />

is because Rails will automatically call to_i on string arguments passed to find. To see<br />

this in action, you can do this in an irb session:<br />

"1-make-it-shiny".to_i<br />

547

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

Saved successfully!

Ooh no, something went wrong!