wrong number of arguments (4 for 1..3) - ruby-on-rails

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

Related

Error with a link action to delete a record

I am creating a link to delete a record from the database, the link calls a destroy method that is responsible for doing the deletion.
Link:
<%= link_to "Eliminar el articulo", options = {:action => destroy, :id => #article.id}, html_options = {:method => :delete, :data => { :confirm => '¿Estas seguro?' }, :class => 'btn btn-danger'} %>
Routes.rb:
delete 'articles/:id' => 'articles#destroy'
Controller:
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to root_path
end
To be more concise, I would like to say that I can locate the problem in the link since what fails is :action => destroy but if I remove the link, what it does is go to the same page instead of delete the record.
The error: undefined local variable or method `destroy' for #ActionView::Base:0x000000000395d0
The text is translated using Google Translate. To see the original question click here
The error: undefined local variable or method `destroy' for #ActionView::Base:0x000000000395d0
destroy variable is not defined in the view... you should use a symbol instead (:action => :destroy)
<%= link_to "Eliminar el articulo", options = {:action => :destroy, :id => #article.id}, html_options = {:method => :delete, :data => { :confirm => '¿Estas seguro?' }, :class => 'btn btn-danger'} %>
However, I suggest to use the route helpers:
delete 'articles/:id' => 'articles#destroy', as: :article
# or user rails resources
# resources :articles, only: [:destroy]
<%= link_to "Eliminar el articulo", article_path(#article), method: :delete, data: { confirm: 'Are you sure?' } %>
Try this
= form_tag(article_path(#article), method: :delete, remote: true) do
= button_tag(type: 'submit', class: 'btn btn-danger') do
= content_tag(:strong, 'Delete')

How to work with ajax when showing different partials - Rails 3

So I was wondering how to work with the link_to method and ajax in Rails 3, when redering different partials.
Example:
Let say I have two link in show.html.erb and every link have a partial to render.
<li><%= link_to "Group1", user_path(#user), { :action => 'group1' , :method => :get, :remote => true} %></li>
<li><%= link_to "Group2", user_path(#user), { :action => 'group2' , :method => :get, :remote => true} %></li>
And we are going to render the partials in this div:
<div id="profile-data">
...render here...
</div>
In the UsersController we have our call methods for each partial:
def group1
respond_to do |format|
format.js
end
end
def group2
respond_to do |format|
format.js
end
end
And of course we have our js files in the view user folder:
group1.js.erb
$("#profile-data").html("<%= escape_javascript(render(:partial => 'group1')) %>");
group2.js.erb
$("#profile-data").html("<%= escape_javascript(render(:partial => 'group2')) %>");
So my question is:
is this the right way to render different partials with ajax? Are I missing something? Do have to route them some way?
This code dosent work right now and I dont know why, any help would be appreciated.
You need to explicitly state that you want to make a javascript request in your link_to.
This can be done be setting the format in the options hash to js with: :format => :js.
So in your case it should look like this:
<li><%= link_to "Group1", user_path(#user), { :action => 'group1' , :method => :get, :remote => true, :format => :js} %></li>
<li><%= link_to "Group2", user_path(#user), { :action => 'group2' , :method => :get, :remote => true, :format => :js} %></li>
The link_to should be somewhat like
<%= link_to "Group1", {group1_users_path, :format => :js} , :method => :get, :remote => true %>
or
<%= link_to "Group1", {:controller=>:users,:action=>:group1, :format => :js} , :method => :get, :remote => true %>
or if it is a member route and needs user_id
<%= link_to "Group1", {group1_users_path(#user) :format => :js} , :method => :get, :remote => true %>
The second param for link_to is the url options so only the url related option go in it, others should be out of the hash or else they will be just passed as params.
Check out more details at rails cocs they have some neat docs and examples
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
You need to have group1 and group2 in routes file
it should be like
resourses :users do
collection do
get "group1"
get "group2"
end
end
this will add helpers group1_user_path and group2_user_path
I recemmond you to go through rails docs thoroughly
http://guides.rubyonrails.org/routing.html#adding-more-restful-actions

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

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

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