Rails routing error with nested resources - ruby-on-rails

In my application, I have a RecipesController and a CommentsController. All comments belong to a recipe, and can be voted up. Here's a snippet from my routes.rb:
resources :recipes do
member do
put 'vote_up'
post 'comment'
end
resources :comments do
member do
put 'vote_up'
end
end
end
If I run rake routes, I find the following route in the output:
vote_up_recipe_comment PUT /recipes/:recipe_id/comments/:id/vote_up(.:format) {:action=>"vote_up", :controller=>"comments"}
The CommentsController has a method called vote_up.
Also, linking to the route works (from my view)
<%= link_to 'Vote up', vote_up_recipe_comment_path(#recipe, comment), :method => 'put' %> <br />
However, clicking on that link gives me the following error:
Routing Error
No route matches "/recipes/7/comments/4/vote_up"
What am I missing? I'm not sure how to debug this, because as far as I can see the route should match.

I think that you get this error message because the request is made via HTTP GET method, not PUT.
In order to create links that use POST/PUT/DELETE method, your application should correctly load a Javascript Rails adapter.
Check that your app has jQuery (http://github.com/rails/jquery-ujs) or Prototype JS adapter and that your layout correctly loads it.

try the following tweak: send the put method as a symbol
<%= link_to 'Vote up', vote_up_recipe_comment_path(#recipe, comment), :method => :put %>

Related

No route matches [POST] "/articles/new" - Why?

I made the following introduction:
http://guides.rubyonrails.org/getting_started.html
And after that, I wanted to create a new field (like title) and got the error notification:
Here is my code:
routes.rb
Rails.application.routes.draw do
get 'welcome/index'
resources :articles do
resources :comments
resources :description
root 'welcome#index'
# For details on the DSL available within this file, see guides.rubyonrails.org/routing.html
end
end
I know that this question has been asked a lot but their solutions didn't helped me.
What should I do?
Regards
The problem is in your new.html.erb form, you are missing url: articles_path, if you don't specify it, the form will be sent to the same action (i.e. new). So, since submitting the form uses POST (by default) method, you get:
No route matches [POST] “/articles/new”
You need to change your form_for and specify the url, like this:
<%= form_for :article, url: articles_path do |f| %>
From the same link your provided:
There's one problem with this form though. If you inspect the HTML
that is generated, by viewing the source of the page, you will see
that the action attribute for the form is pointing at /articles/new1.
This is a problem because this route goes to the very page that you're
on right at the moment, and that route should only be used to display
the form for a new article.
1 My emphasis.
By default rails new resource route has a GET HTTP verb, not POST. Unless you specified otherwise.
Seems like you are using new_article_path or articles/new in the form
<%= form_for :article, url: new_articles_path do |f| %>
Change it to
<%= form_for :article, url: articles_path do |f| %>

Hide search params in Rails4 url (param not found: ---)

I wanted to hide params in rails url while searching.
so previously my link is like this,
http://localhost:3000/photos?utf8=%E2%9C%93&room_ids[]=534b6cc56d696e0f000d0000&commit=Refine+Search
i wanted to achieve like below link,
http://localhost:3000/photos
So i have changed the form_tag method to Post from Get.
<%= form_tag photos_path, :method => 'post' do %>
...
<% end %>
In route file mentioned as,
match '/photos/index', via: :post
After doing it giving error as,
ActionController::ParameterMissing in PhotosController#create
param not found: photo
How to achieve it!!!
If you want custom action to be performed on the params, better write a method in controller
#photos controller
def customize
#custom action on params
end
add the method 'customize' in the routes and specify the route in the form.
Also, if your form doesn't have any fields from Photo model, you can use ActiveModel::Model for projecting an object. Checkout http://blog.remarkablelabs.com/2012/12/activemodel-model-rails-4-countdown-to-2013 and http://prasadsurase.github.io/blog/2014/02/19/using-activemodel-model-for-devise-based-invitations/ describing about how to use ActiveModel::Model.
<%= form_tag photos_index_path, :method => 'post' do %>
or
match '/photos/index', via: :post, as: :photos
In termial, type rake routes
match '/photos/index' => photos_index /photos/index photos#index
match '/photos/index', via: :post, as: :photos => photos /photos/index photos#index
According to Rails Guide
Never use the legacy wild controller route. This route will make all actions in every controller accessible via GET requests.
# very bad
match ':controller(/:action(/:id(.:format)))'
Don't use match to define any routes. It's removed from Rails 4.

Rails form_for wrong method

I've got a weird issue with one of my forms. The form only changes one variable of the object, called admin_comment. It ends up in the show method of the controller, in the terminal:
Processing by EnrolmentsController#show as
Here is the form_for
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :get, remote: true do |f| %>
And here is the rake routes
enrolments_admin_comment GET /enrolments/admin_comment(.:format) enrolments#admin_comment
And the routes.rb part
get "enrolments/admin_comment"
resources :courses do
resources :enrolments
end
When I delete the method: :get part from the form_for, it ends up at the update method.
Everything else with the enrolments controller/model works fine. Does somebody know what's going on here? Thanks!
Update
After nearly getting insane I've got it working like this, but only with :get as method.
routes.rb
get "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
form_for
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :get, remote: true do |f| %>
If I change the method to :post, I get the following error:
ActionController::RoutingError (No route matches [POST] "/enrolments/28/admin_comment"):
Two questions came up:
1. What do I have to change to make it work with :post?
2. As far as I understand, if I just would just state the controller and the verb (:get / :post / ...), rails would know which method it has to use as the verbs are mapped to the methods. But when I state the whole path (controller and method), shouldn't rails know everything it needs without the verb? The form params are being sent anyway.
Update2
Ok, I've changed
get "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
to
post "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
Now everything works fine.
You'll be best looking at Rails' Resource Routing
HTTP Verbs
Each resources :controller you create in your routes.rb file creates a series of routes, which connect with relative HTTP Verbs:
The HTTP verbs part of the routing system is the most important, as it governs which controller action is loaded. You can use the same path helper with different HTTP Verbs to route to completely different controller actions
If you want to create a new path, you'd need to set the HTTP verb to method: :post, like this:
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :post, remote: true do |f| %>
Routes
Perhaps you'd be better with this routing structure:
resources :courses do
resources :enrolments do
get :admin_comment, shallow: :true
end
end

NoMethodError when rendering a form Rails

routes.rb:
resources :shops
shop_controller.rb:
def new
#shop=Shop.new
end
new.html.erb:
<%= form_for(#shop) do |f| %>
....
<% end %>
error:
undefined method `shops_path' for:
<%= form_for(#shop) do |f| %>
The problem is that I already specify the shop resources in the routes file.
Why still get such kind of error?
Any help will be appreciated, thanks
You should use ShopsController not ShopController due to Rails naming convention.
Make sure you have these lines in your rake routes output:
shops GET /shops(.:format {:action=>"index", :controller=>"shops"}
POST /shops(.:format) {:action=>"create", :controller=>"shops"}
OR
shops POST /shops(.:format) {:action=>"create", :controller=>"shops"}
If they aren't present, look carefully at your routes.rb for possible with_options, scope or any other scoping that can affect your resources :shops in such a way that it doesn't generate default url helpers.
since u havent specified the method in the form tag, i guess it is going as a GET request. Try adding the method to ur form
<%= form_for(#shop), :method => :post do |f| %>

ruby on rails form not doing correct action

I'm trying to edit a form, the route is controller/id/action for edit so for example
people/124321/edit
I'm trying to make this form submit to the update action using this code:
<% form_for :probe, #probe, :action => "update" do |f| %>
...
...
...
<%= submit_tag 'Submit' %>
<% end %>
When I click submit, it gives me an error stating
Unknown Action.
No action responded to (id).
Edit
The only thing in my routes specified for probes is map.resources :probes
RoR just did the people/124321/edit by itself when I generated the controller.
Rake routes shows this
probes GET /probes(.:format) {:controller=>"probes", :action=>"index"}
POST /probes(.:format) {:controller=>"probes", :action=>"create"}
new_probe GET /probes/new(.:format) {:controller=>"probes", :action=>"new"}
edit_probe GET /probes/:id/edit(.:format) {:controller=>"probes",action=>"edit"}
GET /probes/:id(.:format) {:controller=>"probes", :action=>"show"}
PUT /probes/:id(.:format) {:controller=>"probes", :action=>"update"}
DELETE /probes/:id(.:format) {:controller=>"probes", :action=>"destroy"}
Edit 2 Probe Controller
def edit
#probe = Probe.find(params[:id])
end
def update
#probe = Probe.find(params[:id])
debugger
if #probe.update_attributes(params[:probe])
flash[:notice] = "Successfully updated probe."
redirect_to probes_path
else
render :action => 'edit'
end
end
It's hard to say exactly since you have posted very little supporting details for your question, but my guess is that your routes file is set up such that the precedence of something matching :controller/:action/:id comes before the route you're aiming for, :controller/:id/:action.
Routes are evaluated top-down, first match wins.
I'll echo John's answer, too. You shouldn't need to specify :action => 'update', and in fact these days I usually extract the form out of both new.html.erb and edit.html.erb into a partial _form.html.erb. form_for will figure out if the object is a new record and POST to either the create or update action, as appropriate.
I have seen some situations in the past where route changes reloaded in development mode confuse the routing code, which is usually fixed by restarting the server.
rake routes is also a good debugging tool. Check the page source to see what Rails has used for the form's action attribute, then scan down the output of rake routes to see where the request will end up.
If you're using RESTful resources, then you should just be able to do this:
<% form_for(#probe) do |f| %>
.
.
.
<%= f.submit 'Submit' %>
<% end %>
Rails can work out whether you're creating a new record or updating an existing one. See Binding a Form to an Object for further details.
Also, note the use of f.submit in my example. The *_tag helpers go together, so you wouldn't usually see a form_for helper with a submit_tag.
"Unknown Action. No action responded to (id)." sounds like a routing problem.
Have you removed or commented out the default routes in your routes.rb file?
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
If the default routes are being run it could be swapping the id for the action?

Resources