Named routes: why destroy_message_path doesn't work? - ruby-on-rails

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 %>

Related

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 %>

Devise/ Delete user Error

I am creating a form for an admin to go in and list, edit and delete users. I have tried many different variations for deleting a user and nothing works. I am wondering if it is because I need to use devise_for :users and resources :users in my routes.rb. This is because I have uploads/attachments linked to users. But here is my link
<%= link_to 'Delete',user, :method => 'delete', :confirm => 'Are you sure?' %>
And my routes.rb
# devise_for :users
devise_for :users do
get "/users/sign_out" => "devise/sessions#destroy", :as => :destroy_user_session
end
resources :users do
resources :attachments
end
The error I am receiving is The action 'destroy' could not be found for UsersController.
But my users controller has
def destroy
#user = User.find(params[:id]).destroy
redirect_to admin_index, :flash => { :success => 'User was successfully deleted.' }
end
If you are not using ajax for the requests, the problem is taht you ar using a link_to
In order to send the :method => 'delete' you have to use a button, jus like this:
<%= button_to 'Delete', user, :method => 'delete', :confirm => 'Are you sure?' %>
Because destructive action must be performed with a form submission:
http://www.w3.org/2001/tag/doc/whenToUseGet.html#checklist

Why are id's from nested route switched around?

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

Posting to controller via link_to

I am trying to send a :vote parameter of 'up' to my controller, so that it performs the voting function of current_user.vote_exclusively_for(#book). I am using the thumbs up gem.
I am trying to do this using link_to, and the correct parameters are showing up in my server output, but it is not working with the controller. I must be doing something wrong, but I am not sure what. Do i need to do something different with routes, other than books :resources?
This my vote action in books_controller
def vote
#book = Book.find(params[:id])
if params[:vote] == 'up'
current_user.vote_exclusively_for(#book)
end
redirect_to #book
end
And this is the link_to example in my view:
<%= link_to "Vote Up", :url => { :controller => "books", :action => "vote", :vote => "up"}, :method => :post %>
Any advice on where my attempts are breaking down would be greatly appreciated ( extra note: when i put the current_user.vote_exclusively_for(#book) function in my view it works) so I think this is a view/routes/link_to issue, not the function itself.
I don't understand your link_to. It seems to be missing the ID of the book it's voting on?
Make sure your routes.rb file looks like this:
resources :books do
post :vote, :on => :member
end
Then change your link_to function to this:
link_to "Vote Up", vote_book_path(#book, :vote => "up"), :method => :post
I just had a similar problem and solved it by using this style syntax:
<%= link_to "Vote Up", {:controller => "books", :action => :vote, :vote => "up" }, {:method => :post} %>
Also make sure your routes.rb has something similar to
resources books do
post :vote
end

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