问题
Let's say I have methodA
def methodA
note = Note.find(params[:id])
note.link = params[:link]
note.linktype = params[:linktype]
note.save
redirect_to(notes_url)
end
When I call this method from a view like this, it works fine
<%= link_to image_tag(w.link, :border =>0), methodA_path(:linktype => w.linktype, :link => w.link, :id => @note.id) %>
But, if I call the method from another method in the same controller like this:
def methodB
...
methodA(:id => params[:id], :link => link, :linktype => "image")
end
I get this error:
wrong number of arguments (1 for 0)
The parameters that methodA is getting are still the same parameters that methodB got, not the ones that I'm sending from methodB. How do I get around this problem? Thank for reading.
回答1:
Several things:
- The Ruby, and therefore Ruby on Rails, naming convention is to use underscore notation rather than camelcase. So it should be
method_arather thanmethodA. - It looks like
methodAis a controller action. If you look at your method signature, you're not actually defining any method parameters. That's a good thing: actions don't take any. - The
paramscall in themethodAaction is not accessing method parameters, but is access the Rails request params hash. - In your view, you're not actually calling the method. Rather, you're linking to the action, which, when clicked, initiate a request that is routed to that action. The actual method you're calling is
methodA_path, which is generating the URL. This is a shortcut to url_for that automatically fills in some parameters for you (the other ones are in the hash you're passing). This method was automatically generated for you from your routes. Do arake routesfrom the root of your app for a little more information. - If you wanted to call the action method from
methodB, which is probably unwise, you don't need to pass it the parameters. SincemethodBis also an action being called in its own request cycle, theparamshash is still available tomethodA, and it will find all of those things just fine. I'd suggest, however, extracting any common functionality into a third helper method and calling that from each action; calling actions from other actions feels like a code smell to me.
A bit of a summary: methodA and methodA_path are different methods. The former takes no parameters but accesses the Rails request parameters hash, while the latter takes parameters to pass to url_for.
This is all pretty basic, so I strongly suggest you read Agile Web Development with Rails (3rd edition for Rails 2, 4th for Rails 3).
回答2:
A call to method_a_path and method_a are not the same.
The
method_adoes not take parameters. It accesses the parameters from theparamshash set to the controller instance during action invocation.The
method_a_pathdoes not invokemethod_a, it just generates the URL for invoking the method. Actual invocation happens when the user clicks on the link and the rails server processes the request.
If you want to reuse the method in a diffrent context extract the code of the action to a new method as shown below:
class PostsController < ApplicationController
def add_media
add_media_with_para(params)
end
def action2
add_media_with_para(:id => params[:id], :link => link, :linktype => "image")
end
private
def add_media_with_para p = {}
note = Note.find(p[:id])
note.link = p[:link]
note.linktype = p[:linktype]
note.save
redirect_to(notes_url)
end
end
Now in your view you can obtain the path to add_media action as follows:
posts_add_media_path(:linktype => w.linktype, :link => w.link, :id => @note.id)
回答3:
I assume by addMedia you mean methodA
Note, method methodA_path is not the same as methodA. First one is automatically generated because you have a route named methodA and returns url necessary to access that route. Thus, it returns string. While methodA usually renders html template.
If you want to delegate rendering to another action, you can do something like this: redirect_to :action => :methodA, :id => 1, :otherParam => 2
来源:https://stackoverflow.com/questions/3287089/how-to-call-a-method-and-send-new-parameters-in-ror