Dynamic Path Helpers Rails

Dynamic path helpers rails

This section might be helpful http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use

Verb    Path              Action     Helper

GET /photos index photos_path
GET /photos/new new new_photo_path
POST /photos create photos_path
GET /photos/:id show photo_path(:id)
GET /photos/:id/edit edit edit_photo_path(:id)
PUT /photos/:id update photo_path(:id)
DELETE /photos/:id destroy photo_path(:id)

If you want to create a helper for show action you can write

photo_path(@photo.id)

where @photo is your model object. Or you can pass @photo directly if it responds to id method.

photo_path(@photo)
edit_photo_path(@photo)

You can also load rails console (in terminal) and test routes using app like so app.photo_path(1) (it will show you the route for the photo with id equals 1)

How to dynamically call routes helper in rails?

try Rails.application.routes.url_helpers.send(...)

Edit:

As Larry Gebhardt mentioned the url_helpers module is no longer being cached.

Another workaround would be:

cached_helpers = Class.new do
include Rails.application.routes.url_helpers
include Rails.application.routes.mounted_helpers
end.new

cached_helpers.send(...)

Dynamic index path helper

# app/helpers/application_helper.rb
module ApplicationHelper
def albums_path(owner) # change the name if it will collide with a route helper
Rails.application.routes.url_helpers.send "#{owner.class.name.downcase}_albums_path" # add the owner as a second param to 'send' if needed
end
end

Edited!

Helper function for dynamic routes

Just use [:edit, @contact] instead of the explicit method name.

<li><%= link_to '.... Edit', [:edit, @contact] %></li>

Substitute @contact with whichever variable you wish. I find the array syntax much more readable, and prefer it everywhere. Compare:

 = link_to "Edit", edit_user_post_comment_path(@user, @post, @comment)

vs

 = link_to "Edit", [:edit, @user, @post, @comment]

Rails named route with dynamic segments URL generation from model

The best I've been able to come up with: just override the *_path helpers with my own implementation.

If you know a way to make the default helpers work, please chime in!

This problem boils down to one issue: the auto-generated *_path and *_url helpers don't give me the flexibility I want. What I want them to do is trivial, so without another option, I can just write my own:

module ApplicationHelper
def learn_topic_path(topic)
"/edu/#{topic.slug}"
end

...
end

Writing a few _path/_url helper overrides avoids all kinds of complication, and allows you to keep out of to_param, avoid including new plugins, etc.

One could probably go another step forward and generate the static components of the route from known routing rules, as well as infer what attributes one needed to extract from a model if the dynamic segment names line up to the model attribute names, but that starts to break down once you do more complicated things or add multiple models (e.g., 'edu/:topic_slug/:course_slug').

The big downside to doing this is that you now have to update routes in two places every time you change them: the route definition itself in routes.rb as well as the corresponding route helper in application_helper.rb. I can live with that for now.

dynamically intercept and recall Ruby on Rails Routes in Rails Engine

So I got it to work more or less. I didn't find a solution to this exact problem, so I made small trade-offs. Namely, I decided that the administrator of the host application has to make a small change in the routes.
Basically, I now use a scope like in the following example.

scope path: "/#{EmbedMe.scope_name}", as: EmbedMe.scope_name, is_embedded: true

To make it as easy as possible for the user of the engine, I have integrated a custom route function, which handles the scoping of the routes.

# lib/embed_me/rails/routes.rb
module ActionDispatch::Routing
class Mapper
def embeddable
# note that I call the yield function twice, see describtion below
yield
scope path: "/#{EmbedMe.scope_name}", as: EmbedMe.scope_name, is_embedded: true do
yield
end
end
end
end

# [Host Application]/config/routes.rb
Rails.application.routes.draw do
# not embeddable
get '/private', to: 'application#private'

# is embeddable
embeddable do
get '/embeddable', to: 'application#embeddable'
end
end

# output of $rails routes
...
private GET /private(.:format) application#private
embeddable GET /embeddable(.:format) application#embeddable
embed_embeddable GET /embed/embeddable(.:format) application#embeddable {:is_embedded=>true}
...

Note that I call the yield function twice, once to get the routes normally, and once under the scope. This way I also get multiple path helpers for the normal and the embedded link.

Creating the custom route method is handled similarly to Devise. See Source



Related Topics



Leave a reply



Submit