Why are id's from nested route switched around? - ruby-on-rails

I have a nested resource under my admin namespace:
The admin/topic/comments_controller.rb is a resource under admin/topics_controller.rb.
namespace :admin do
resources :topics do
resources :comments, :controller => "topic/comments"
end
end
gives me this delete route:
DELETE
/admin/topics/:topic_id/comments/:id(.:format)
admin/topic/comments#destroy
And I am creating a link to destroy comments, like the following:
# comment = #topic.comment.first
<%= link_to "Destroy", [:admin, comment], :method => :delete %>
produces the following route:
/admin/topics/165/comments/11
All seems correct, except that the two ids are swapped around. What am I doing wrong?

You can use the name_route instead :
<%= link_to "Destroy", admin_topic_comment_path(#topic, comment), :method => :delete %>

<%= link_to 'Destroy', :action => 'destroy', :id => comment.id, :method => :delete %>
or if you use RESTFUL routes:
<%= link_to 'Destroy', delete_comment(:id => comment.id), :method => :delete %>
When working with namespaced controllers and routes, you have to use namespaced models in order for the link_to helper to function properly.
e.g., in app/models/admin/comment.rb
class Admin::Comment < Comment
end

Related

Routing error with confirmed (seemingly) existing route

I'm copying what seems to be identical logic, but it doesn't work with one of my models.
In surveys, I have
View
<% #surveys.each do |survey| %>
...
<%= link_to 'Delete', survey, :confirm => 'Are you sure?', :method => :delete %>
<% end %>
Controller
def destroy
#survey = Survey.find(params[:id])
#survey.destroy
respond_to do |format|
format.html { redirect to '/' }
format.json { head :no_content }
end
end
The delete function works fine.
Yet in question, I have
View
<% #questions.each do |question| %>
...
<%= link_to 'Delete', question, :confirm => 'Are you sure?', :method => :delete %>
<% end %>
Controller
def destroy
#survey = Survey.find(params[:survey_id])
#question = Question.find(params[:id])
#question.destroy
respond_to do |format|
format.html { redirect to #survey }
format.json { head :no_content }
end
end
This gives me the error:
undefined method `question path' for #<#<Class:0x008ff2534....
When I remove the link_to, it works just fine retrieving question and its properties.
Changing the logic in my view to something more specific,
<%= link_to "Delete", :controller => "questions", :action => "destroy", :id => question.id %>
I get a more specific error.
No route matches {:controller=>"questions", :action=>"destroy", :id=>1}
Running rake routes, this confirms the path exists.
DELETE /surveys/:survey_id/questions/:id(.:format) questions#destroy
And here's my routes.rb entry:
devise_for :users do
resources :surveys do
resources :questions do
resources :responses
end
end
end
Computers don't make mistakes, so what did I do wrong?
questions are nested resources, so you should also pass survey to the path:
<%= link_to 'Delete', [#survey, question], :confirm => 'Are you sure?', :method => :delete %>
Assuming that you have set #survey variable.
Question is a nested resource under Survey so your route needs to reflect that. Note that in the rake routes output there's a :survey_id parameter as part of the route. It is required. Therefore your link needs to look like this:
<%= link_to "Delete", :controller => "questions", :action => "destroy", :survey_id => #survey.id, :id => question.id %>
Alternatively you can use Marek's path, namespacing the question resource:
<%= link_to 'Delete', [#survey, question], :confirm => 'Are you sure?', :method => :delete %>

wrong number of arguments (4 for 1..3)

i'm struggling to understand why this is happen with destroy method since everything on controller and routes is ok!
if someone passed through this way please could give me a hint?
Routes
resources :users, :as => "" do
resources :sections, :only => [:new, :create, :destroy, :index]
end
Controller
def destroy
#section = Section.find(params[:id])
#section.destroy
redirect_to sections_url
flash[:notice] = "Section deleted"
end
View
<%= render :partial => "section", :collection => #sections %>
Partial
<%= link_to section.name, section_path(current_user, section) %>
<%= button_to 'Remove', current_user, section, :data => { :confirm => 'Confirm?' }, :class=> "buttom", method: :delete %>
That error means that some function takes 1 to 3 arguments, but you gave to it 4 arguments.
Please see the row number in the error and look up the function, then open documentation and look up how to use that function. Often functions works differently as instance methods and class methods.
The problem seems to be this method call:
button_to 'Remove', current_user, section, :data => { :confirm => 'Confirm?' }, :class=> "buttom", method: :delete
The pair current_user and section has to been passed as an array:
button_to 'Remove', [current_user, section], confirm: 'Confirm?', class: "buttom", method: :delete
Your button_to helper arguments are wrong.
Try this:
<%= button_to 'Remove', {:action => :destroy, :user => current_user, :id => section}, {:data => { :confirm => 'Confirm?' }, :class=> "buttom", method: :delete} %>
codeit, Stefan did what you guys said but did not work, so i tried the path instead and worked!
<%= button_to 'Remove', section_path(current_user, section), :data => { :confirm => 'Confirm?' }, :class=> "button", method: :delete %>

Named routes: why destroy_message_path doesn't work?

I am having a link like
<a href = '/messages/destroy/<%= #showmessage.id %>'>Delete Message</a>
I am rewriting this into
<%= link_to "Delete Message", destroy_message_path(:id => "1") %>
In my routes i have
map.resources :messages, :collection => { :destroy => :get }
And in my controller
def destroy
#message = Message.find(params[:id])
#message.destroy
redirect_to :action => 'index'
end
When I run the page, I am getting the error as:
undefined method `destroy_message_path' for #<ActionView::Base:0xb24a24c0>
How do I resolve this?
I'm not sure if you mean to be fighting against the Rails conventions here, but its alot easier to go along with them, so if you are ok with that you can do the following:
Remove this from your routes:
map.resources :messages, :collection => { :destroy => :get }
Change it to:
map.resources :messages
And use this link format instead:
<%= link_to "Delete Message", message_path(:id => "1"), :method => 'delete' %>
The URL for the destructive action will look like /messages/1, but the "method" portion of that link_to method will make Rails create a hidden form and perform a simulated "DELETE" action against the URL. Which is far more RESTful, and follows along with what Rails is expecting you to do.
With resources, you shouldn't be making a GET request, you should be making a DELETE request like this:
<%= link_to "Delete Message", destroy_message_path(:id => "1"),
:confirm => 'Are you sure?', :method => :delete %>
and in your routes file:
map.resources :messages
On another note, you can just pass in the object of the message to destroy_message_path, so for example:
<%= link_to "Delete Message", destroy_message_path(#message),
:confirm => 'Are you sure?', :method => :delete %>

What is causing this error when I try to edit a RoR object that was created via scaffold?

What is causing this error when I click on the edit button for a note? The delete button works fine. I created the note object with a scaffold.
index.html.erb
<% #notes.each do |note| %>
<%= note.detail %>
<%= button_to 'Delete', note, :confirm => 'Are you sure?', :method => :delete %>
<%= button_to 'Edit', edit_note_path(note) %>
<% end %>
notes_controller.rb
before_filter :check_ownership, :except => [:new, :create, :index, :edit]
def edit
#note = Note.find(params[:id])
end
Error
ActiveRecord::RecordNotFound in NotesController#192
Couldn't find Note with ID=edit
../app/controllers/notes_controller.rb:248:in `check_ownership'
Parameters:
{"id"=>"edit"}
EDIT
config/routes.rb
map.resources :notes
All of the other routes for notes work fine.
Thanks for reading
Scaffold controller's 'edit' action, and defult routing support 'edit' as GET rather than POST request.
If you use link_to rather than button_to, things should work.
Alternatively, change the line containing button_to -
<%= button_to 'Edit', edit_note_path(note), :method => :get %>

button_to :action => 'destroy' looks for 'show'

This seems incredibly similar to a question I had answered just a few days ago, but the solution then isn't working now.
I'm building a rails app, and I am trying to have a button_to trigger a destroy in a different controller.
the code I have for the button is
<%= button_to "delete", :controller => :meals,
:action => 'destroy',
:recipe_id => recipe.id,
:method => :post >
when I click the delete button, i get a
'no matches for meals/3' which is the current meal_id.
the destroy in the meals controller looks like this
def destroy
#meal = Meal.where("current_user.id => ? AND recipe_id => ?", current_user.id, params[:recipe_id]).first
#meal.destroy
respond_to do |format|
format.html { redirect_to :controller => "user" , :action => "show" }
format.xml { head :ok }
end
end
it appears as though the button_to is completely ignoring the :action and requesting show which does not exist and shouldn't exist.
And how you part of routes.rb for that one looks like?
Because if you use map.resources then destroy has same path as show but :method => :delete(which is virtual verb implemented by form and _method=delete param).
Try this:
<%= button_to "delete", {:controller => :meals,
:action => 'destroy', :id => recipe.id }, :method => :delete %>
or if recipe is instance of Meal class then
<%= button_to "delete", #recipe, :method => :delete %>
Mind the curly brackets.
I know it is way too late for an answer but hope it may help somebody(using Rails 4).
<%= button_to "delete", meal_path(:id => recipe.id), :method => :delete %>

Resources