I want to dynamically set the url path of a
- application_path = #object.class.name.underscore + "_path"
= link_to "<input type='button' value='Cancel' class ='bigbutton go_back'/>".html_safe, application_path(#application)
but i keep getting
undefined method `application_path' for #<#<Class:0x00000103d11d80>:0x00000103d04a68>
any ideas on how to achieve this behavior
In the general case, you can use Object#send to call a method based on a symbol (which you can get from a string using to_sym):
send(application_path.to_sym, #application)
From the docs:
send(symbol [, args...]) → obj
Invokes the method identified by symbol, passing it any arguments specified.
But in this case, because your dynamic string is simple enough, Rails has a built-in method to do this, url_for:
url_for(#application)
Example from the docs:
<%= url_for(#workshop) %>
# calls #workshop.to_param which by default returns the id
# => /workshops/5
Note: this is assuming your #application is a model object where the route matches the model name. In your code there seems to be two instance variables, #object and #application, but you haven't explained them fully, so you may need to modify the above to pass in #object instead of #application.
The method url_for does exactly what you're trying to do.
url_for(#application)
Related
I have routes... foo_path, and foo_bar_path. Simple helpers in a link_to.
In the same link, I'm trying to define 2 separate paths...
#foo might be of class Foo, or it might be of class FooBar. It's polymorphic. So, I'd like to build the path with some sort of #foo.class.name.underscore call to prepend to _path.
I can't send it raw with link_to 'foo', "/#{#foo.class.name.underscore}/:id" because I have to send some parameters with it, so only using the route helper works. Unless you know how to send params with that bugger... that'd might simplify things.
Does that make any sense?
Rails will infer the path name from the object type. If you pass a Foo object, it will use foo_path. If you pass a FooBar object, it will use foo_bar_path.
<%= link_to 'foo', foo %>
Assuming foo is one of either a Foo or a FooBar object.
I cover this in-depth in my blog post called "Polymorphic Routes".
I have a model that is responsible for manipulating resource paths. I would like to leverage some Rails routing helpers if I can. I don't want to make any assumptions of the type of resource that is being manipulated, as I would like that to be generic.
http://edgeguides.rubyonrails.org/routing.html#creating-paths-and-urls-from-objects
states that "You can also use url_for with a set of objects, and Rails will automatically determine which route you want:"
<%= link_to 'Ad details', url_for([#magazine, #ad]) %>
From what I've found url_for helpers typically expect a hash that includes the controller, action, etc. What I have been looking for is what the above url_for seems to be returning, which is the resource path from an array of objects. I'm not sure if I'm just using the wrong namespace, but looking through the API docs, I can't find a namespace that would provide the above method.
Just to clarify, I am trying to do something such as below in a model:
resource_array = [parent_resource, child_resource]
resource_path = url_for(resource_array)
I usually keep any routing code out of a model class, but this class is dedicated to manipulating resource paths. Thanks in advance.
Edit:
This is the syntax that I ended up using:
Rails.application.routes.url_helpers.polymorphic_path(resource)
Edit (2):
I feel like there has to be a nicer way to do this, but this is what I have right now.
resource_path = ''
resource_array.each do |resource|
resource_path += '/' + resource.class.name.pluralize.underscore + '/' + resource.id.to_s
end
I'm not sure this is what you're asking for, but url_for is an instance method of the module ActionDispatch::Routing::UrlFor, so you need to extend or include that module to gain access to the method.
I have a helper with a method named search_form like this:
module Admin::BaseHelper
def search_form(*args)
# my great code here
end
end
To call this method in my HAML code, I can do this:
= search_form
= search_form()
= search_form(param1: "value1", param2: "value2"...)
My problem is with this first call. When I do this in any HAML file, it renders my helper. Except if my file name is _search_form.html.haml. Is that case, it returns nil.
If I put a raise error in the helper, I notice that my method isn't being called, but I am not able to find what is being called and why.
If I use the syntax on the second and third lines, it works as expected by calling my helper method.
So my question is: is this standard Rails behavior or a bug?
By default, Rails will look for a local variable with the same name as your partial, which may conflict with existing method names.
One way to get around this is to simply redefine the method inside your partial:
<% search_form = self.search_form %>
# Rest of the partial's code
I'm new to Rails and had a doubt regarding the link_to method. The second argument should be the url of the link, which one can generate using the url helper methods. However, one may need to pass :id as an argument of the helper method, which can be done by passing an object (which has :id as one of its attributes).
Well, in one case I did not pass the object to the method (in one of the views). However, the url was still able to obtain the correct :id (presumably using an instance variable defined earlier).
How did Rails choose a value for :id when I didn't even pass in any object?
Thanks a lot!
Edit
Here's the relevant code:
link_to 'Find Movies With Same Director', same_dir_path
Here, I am on a "show" page with url /movies/1. The same_dir_path is the helper method for the URL /movies/same_dir/:id where :id would be that of the passed object and movie#same_dir is the controller#action. Note I did not pass any object to the helper method link_to and yet, it takes the :id from the previous url ('1' in this case). The URL isn't even relative to the previous one (the path is different).
This is the controller method (same_dir):
def same_dir
#movies = Movie.find(params[:id])
if (#movies.director.nil? || #movies.director == '')
flash.keep
redirect_to movies_path
flash[:warning]="'#{#movies.title}' has no director info"
return
end
#otherMovies = Movie.find_all_by_director(#movies.director)
end
This is the routes.rb code:
match 'movies/same_dir/:id'=> 'movies#same_dir', :as => :same_dir
resources :movies
After reading your updated question I can provide you with a better answer:
Rails controllers can have default url options via the url_options method. (Doesn't seem to be a very documented feature. (here and here))
By default this method returns the parameters from the current request and that is where the id is coming from.
You can override it, too:
def url_options
{ my_parameter: my_value }.merge(super)
end
Original answer (might still be useful):
What you are witnessing is most likely a browser feature. For example this code:
link_to "Show", ""
generates this HTML code:
Show
If you click that link in a browser it navigates to the empty url relative to the current url, which is in fact equal to the current url.
Another example:
link_to "Publish", :publish
generates:
Publish
Now if your current url is http://localhost/articles/1/edit that link will take you to http://localhost/articles/1/publish. (Notice that the final url contains the model ID even though you are not having it in the HTML source)
In both cases your current model ID is preserved by the browser because you are using relative urls.
This behaviour might give you the illusion of some magical model ID detection, especially because browsers preview the final (=absolute) url when hovering over the link.
Have a look at the source, I'll bet your generated links do not contain any model IDs.
i have a helper function which renders a partial and i pass a variable called method with it into the view...
when in view i use
<%= friend.method.profile.picture %>
the method variable can be either user or friend
and i get
wrong number of arguments(0 for 1)
i suppose there is a problem how i use the variable being passed into the association call... maybe i have to escape it somehow?
If I understand what you want, you are trying to dynamically call a function based on the value of a string argument called 'method'. Also, 'method' is an existing function in Ruby, (hence your error message about 'wrong number of args' vs 'undefined method'), so I would recommend renaming it in your code.
TLDR:
Rename your variable something like "person" (instead of 'method'), then
try some meta-programming to call the function using send:
friend.send(person).profile.picture
Here is the same answer as ~AmirRubin, but fleshed out more.
I am assuming that friend was the object, method was the helper, .profile is the method you want the helper to use.
Define your helper as:
def call_method(object, method_name)
object.send(method_name)
end
In your view call it as:
<%= call_method(friend, :profile).picture %>
Adjust this if my assumptions are wrong. If you need to send the method name (symbol) to the partial pass it in the locals.