2

Is it possible to "build" a path in an erb file like this? The path's name should be dependent on the object's class name. The path being build already exists in the routes.rb file. I just want to dynamically choose a part of the path being generated so I don't have to use a conditional and repetitive code.

  <% custom_path = "hide_#{object.class}_path" %>
  <%= link_to 'Do something', custom_path(object) %>

The above example doesn't work because I don't know how to "use" the new path correctly. I guess I have to "call" the route by some "meta" way? Like object.call(method) in Ruby. But I don't know how to do this in Rails.

An example to clarify: let's say the object's class is Car, then the path in the variable should be: hide_car_path.

The error for the example above looks like this:

undefined method `custom_path' for #<#<Class:0x00000108afac40>:0x000001091fd3a8>
Linus
  • 4,643
  • 8
  • 49
  • 74

4 Answers4

3

We use eval() for this:

<%= link_to 'Do something', eval("custom_#{object.class}_path(object)") %>

I'm not sure what it does (not many people like eval), and I'm not sure whether the passed variable will persist in my example above, but we do use the above code in our own applications

Richard Peck
  • 76,116
  • 9
  • 93
  • 147
1
<% custom_path = "hide_#{object.class}_path" %>
<%= link_to 'Do something', custom_path(object) %>

When you do this, you're making a variable called custom_path and setting it equal to a string. You then call the string as if it was a method. It's like doing this:

foo = "Bar"
foo("baz")

which is like

"Bar"("baz")

The second argument to link_to is just a string: the path we want to call, like "hide_cars". The path helpers are just there to help you define that string. Note that the actual url itself DOES NOT have the word "path" in it:

You can do this:

my_path = custom_path(object)

then do

link_to "Do Something", my_path

In your case, however, you want to change the path that's called dynamically, which is a complicated way of getting the resulting string. It might be simpler for you to do this instead:

link_to "Do Something", "/hide_#{object.class.name.undescore.pluralize}"

This assumes that the url you want to get is "hide_cars".

Max Williams
  • 32,435
  • 31
  • 130
  • 197
1

Use eval() to do this. eval is used to execute the things which was qiven as string.

for example eval(2+2) # 4

likewise

 <%= link_to 'Do something', eval("hide_#{object.class}_path(object)") %>
Can Can
  • 3,644
  • 5
  • 32
  • 56
0

Thanks for all the answers. They didn't (only in my case?) work but pushed me into the right direction. The solution was a bit "different" than in the answers though, as I couldn't just use the class name.

The working solution is:

  <% path = "approve_#{object.class.to_s.downcase}_path(object)" %>
  <td><%= link_to 'Do something', eval(path) %></td>

If I do the following, like in the answers I became:

  <% path = "approve_#{object.class}_path(object)" %>
  <td><%= link_to 'Do something', eval(path) %></td>

I get the following error:

undefined method `hide_Car_path' for #<#<Class:0x00000108afac40>:0x00000101bea990>

I figure the object's class in the path has to be lower case. Thanks everyone!

Linus
  • 4,643
  • 8
  • 49
  • 74