integration test not calling destroy


I'm writing to describe a problem I ran into, and the solution, which I've already found, for posterity's sake, b/c it took a very long time to figure out. While I don't consider myself a rails newbie, this does qualify as a rookie mistake.

I was having an integration test fail because its call to my one of my app's destroy controller methods did not appear to be firing. Along the way, I tried renaming destroy to destroy2, and that "solved" the problem. Except it failed to explain the actual problem.

It turned out that I was mistakenly using 'get' instead of 'post' in the integration test to trigger the method.

For those of you that haven't run into this yet, the reason this was a problem is that magic line that scaffolding puts into every controller, that looks like this:

   verify :method => :post, :only => [ :destroy, :create, :update ],
          :redirect_to => { :action => :list }

This traps non-post HTTP calls to the listed actions, and redirects them to a safe action. The purpose of this is to make sure that (hopefully) all GET requests are non-destructive. This, as you probably do already know, is to make sure that web crawlers (e.g. search engines) don't accidentally modify your databases.

In my case, the reason I was using get was that I was equating it to a simple hyperlink in one of my templates, rather than a submit button on a form. However, the hyperlink in question was *also* generated by scaffold, and it (correctly) had :method => :post set, for exactly the same reason.

Of course scaffolding can't predict what other destructive methods you might write; technically, you ought to add any destructive method to this list, and then only call it via a post. I can't wait to find out how many places I've failed to do that...

HTH someone...


"In the beginning, there was nothing. And God said: 'Let there be light!' And then there was still nothing, but you could see it."