Ruby on Rails - Setting a Custom Route with Custom Action

i'm a RoR beginner using rails 3.2.3.

I have a products resource and a nested Availability resource under it.

My routes are:

/products/:product_id/availabilities

which is working great.

However, my availability model allows to set the price of the product on an exact date, for e.g.: today the product 'x' will have 'y' availability (it is an integer) and 'z' price (price is also an attribute of the Availability Model).

My question is, I now want to add a page that allows the modification of prices (without creating a new Price Model), similar to the one I have for availability. I'm only using the index action, as it will show all the availabilities for that only selected product.

How can I create a route like:

/products/:product_id/availabilities/prices

I tried adding this to my routes rb:

 match '/products/:id/availabilities/prices', :action => 'indexP', :via => [:get], :controller => 'prices'
 match '/products/:id/availabilities/prices', :action => 'createP', :via => [:post], :controller => 'prices'

It is worth noting that I am using a prices controller to interact with the same availability model, but that shouldn't be a problem.

I also created in that prices controller the indexP and createP actions. In my Availabilities View I created an indexP.html.erb to differentiate from the regular index.html.erb which contains the availabilities.

And when I run rake routes I get:

$ rake routes | grep prices
                            GET    /products/:id/availabilities/prices(.:format)
                            POST   /products/:id/availabilities/prices(.:format)

Which is great. However, when I access that URL, I get:

NoMethodError in Availabilities#show
{"product_id"=>"46",
 "id"=>"prices"}

Why is it doing the show action instead of my custom match?

Note: I am not after something like: /products/:id/availabilities/:id/prices

just :/products/:id/availabilities/prices

I know this is probably a dumb question but I would appreciate any tips to help me understand what is going on.

Thanks in advance, regards

Answers


How is your product model setup?

If it something like:

resources :products do
  resources :availabilities
end

the first match the route does goes to the show action of the availabilities controller.

You have two options here. Limit the availabilities controller scope, with:

resources :products do
  resources :availabilities, :only => [:index]
end

or to place your custom match before this block

match '/products/:id/availabilities/prices', :action => 'indexP', :via => [:get], :controller => 'prices'
match '/products/:id/availabilities/prices', :action => 'createP', :via => [:post], :controller => 'prices'

Note that this routes are not restfull. This may get you in trouble later :)

Hope this helps.


Need Your Help

How to get the string instance in guice

java dependency-injection annotations guice

Lets say I have binded my strings in guice like this