Posted on March 28, 2007
Subscribing to the RSS Change Log feed to the Subversion repository for Ruby on Rails is a great way to stay on top of what’s going on in Rails land and helps to give you a leg up on the types of things that are coming down the pipe. Today I saw Changeset 6485 and it was quickly blogged about by Dave Thomas. This changeset removes the use of the semicolon in RESTful routes and reverts it back to the old slash way of indicating sub resource intent. What this means is that a route like:
/categories/1;edit
will now become (or should I say become once again)
/categories/1/edit
In addition we get niceties like:
/categories/recent
/categories/1/stamp
I’ve never liked having the semicolon in the url; it just smelled of ugliness. I think we’ll find that this change is a good one and one that allows us to have the benefit of RESTful urls while still allowing for legitimate variations on that theme to support sub resources.
Filed under: Rails |
Tagged with: rest |
Posted on March 27, 2007
I just spent about an hour trying to figure out why none of my RESTful routes were working properly within my RSpec controller specs. In my controller I had some boilerplate code like this:
# POST /categories
# POST /categories.xml
def create
@category = Category.new(params[:category])
respond_to do |format|
if @category.save
flash[:notice] = 'Category was successfully created.'
format.html { redirect_to category_url(@category) }
format.xml { head :created, :location => category_url(@category) }
else
format.html { render :action => "new" }
format.xml { render :xml => @category.errors.to_xml }
end
end
end
The line causing the problem was:
redirect_to category_url(@category)
I kept receiving an error on the eval of category_url with an error description of “can’t convert Fixnum into String”.
I tried replacing @category with @category.id to see if I would get different results. The error went away but the test failed indicating that the id returned from the @category instance was not the same as I was expecting. This led me to determine that I needed to stub out the id property on my class. So I added the following to my setup:
@category.stub!(:id).and_return(1)
Everything worked. Problem solved. But wait, that’s ugly and smells of something wrong. I should be able to just pass the object to the category_url and have it return the correct value. What I did next was go down a rat hole trying to figure out what the named route was sending to the object to get the id. I had assumed id, but in fact it’s to_param, which I had already stubbed out as follows:
@category = mock_model(Category, :to_param => 1)
So what’s the problem? It turns out that to_param must return a string. Makes sense. I changed it to the following and everything worked perfectly:
@category = mock_model(Category, :to_param => "1")
It’s little things like this that make learning so much fun. This issue is really indicative of a much bigger problem—my lack of understanding mocks and stubs. But, I’ll have more to write about this later.
Filed under: Rails Testing |
Tagged with: rest |