Jake Scruggs

writes ruby/wears crazy shirts

So I had this form in a Rails view that needed some changes so, amongst other things, I changed this:
form_tag(:action => 'search')

to this:
form_tag(:action => 'show', :method => :get)

I had noticed that the show and search methods essentially did the same thing (and had the same views) -- which I why I refactored. However, when I made the change I got a 500. I was using restful routes and this form needed to be a get -- which I thought I had indicated. But I had not -- what should have put in the view was this:

form_tag({:action => 'show'}, {:method => :get})

There's this idiom in Ruby where we don't put curly braces around hashes if we don't need to, but I've consistently lost a bunch of time to mistakes like the one above. So I'm thinking about explicitly denoting hashes with curly braces in my future Ruby code just to improve intentionality.

4 comments :

Micah said...

This one has bitten me before as well. I'd agree that using braces in this case would clarify the code. I also think the API would nicer if it accepted just one hash and sorted out the elements itself.

pragmatig said...

wrong solution to a valid problem imo

There is no obvious difference between changing :x=>1 to :x=>1 :y=>2 and {:x=>1} to {:x=>1,:y=>2}

The only problem-solving method would be to use {:x=>1},{} for every call, but who wants to do this...

Anonymous said...

Yeah, taking 2 hashes as params is just plain bad ruby api design. Dealing with it for so long that I'm used to it, but I hope that doesnt stop the core team from fixing form_tag to work with :url and :html parameters like all the other form helpers.

Jared said...

It's a Ruby-ism for the interpreter to gather all the trailing arguments as a hash, even without the curlies. The reason you were seeing the 500 errors is because form_tag will actually take two hashes as arguments, a url_for hash, and an HTML options hash.

You could actually write you code to look like:

form_tag({:action => :create}, :method => :post)

And it would still be valid.