views:

67

answers:

2

According to rake routes, there's the same path for getting an index of objects as there is for creating a new object:

cars GET    /cars(.:format)    {:controller=>"plugs", :what=>"car", :action=>"index"}
     POST   /cars(.:format)    {:controller=>"plugs", :what=>"car", :action=>"create"}

Obviously, the HTTP verb is what distinguishes between them. I want the "create" version of the cars_path method, not the "index" version. My question is what route method do you invoke to choose the one you want? I'm telling cucumber what path to generate with this:

when /the car plug preview page for "(.+)"/
  cars_path(:action => :create, :method => :post)

...but it always chooses the "index" action, not "create". I've tried lots of combinations for the hash argument following cars_path and nothing changes it from choosing "index" instead of "create".

I'll get an error like this:

cars_url failed to generate from {:controller=>"plugs", :method=>:post, 
:what=>"car", :action=>"create"}, expected: {:controller=>"plugs", :what=>"car",
:action=>"index"}, diff: {:method=>:post, :action=>"index"} 
(ActionController::RoutingError) 

This seems like a very simple question but I've had no luck googling for it, so could use some advice. Thanks.

+2  A: 

Since the URL is the same for both actions, you can use cars_path (without arguments) in both cases. You just simply have to make sure that the form's method-parameter is set to :post. You can not set the method via the URL, you need to set it for the form (and you can't reach the create action by using a link, you need to use a form).

sepp2k
Thanks, but I want to call the POST form of the cars_url method from cucumber noninteractively, not from an interactive form in a webpage. Is this impossible? (!!)
Jason
@Jason: `cars_url` is simply a method that returns the string `"/cars"`, it does not care about get or post at all. Only the method that uses the string returned by `cars_url` can affect whether a get or post request is made. I don't know Cucumber, but in Test::Unit you have different methods for get- and post-requests. So to test the create action, you'd simply use `post(cars_path, options)` instead of `get(cars_path, options)`.
sepp2k
the method "cars_path(:action => :create, :method => :post)" is supposed to do what you describe (that's a rails method, not anything special to cucumber). but it always uses "index" instead of "create". is this a bug?
Jason
@Jason: The method `cars_path` returns a string which represents an url. It can not possibly affect whether the method which accesses that URL uses get or post.
sepp2k
so am i misusing the method? Does it not accept a hash of options or objects?
Jason
It does accept a hash, which is the same as the hash that url_for accepts. If you pass `:method => :post` it will simply add `?method=post` to the string it returns (because it assumes that the keys in the hash are supposed to be parameters that you want to go in the params hash - `:foo => :bar` would cause `?foo=bar` to be appended to the URL).
sepp2k
That's helpful- so maybe my real question is how do I make a post call to a create method in my controller? I found http://travisonrails.com/2007/11/07/http-get-and-post-requests-with-ruby but it's not a drop-in replacement.
Jason
A: 

The difference is that one is accessed when a POST is performed, the other is accessed when a GET is performed. Typing a URL into the browser or (typically) clicking a link is the equivalent of a GET action. POST actions are typically performed by form submissions.

imightbeinatree at Cloudspace