Rails polymorphic routes

Posted on Wed Aug 19 2020

Rails polymorphic routes are a smart way to generate paths for Active Record model instances. Suppose that you are working on an application that allows multiple models to be liked.

For example, if you have Post and Comment models, that could be liked by a user, to generate the routes for liking a post or a comment, we could write:

# routes
resources :post do
member do
post 'like', to: 'likes#create'
delete 'dislike', to: 'likes#destroy'
resources :comment do
member do
post 'like', to: 'likes#create'
delete 'dislike', to: 'likes#destroy'

We can refactor these routes using concerns, but for the sake of this post, let's keep it that way.

I prefer using member routes here, because it generates more meaningful paths in this particular case. Consider having like_post_path instead of post_likes_path if you used nested resources. The pathname also reflects that action being taken by the user.

Another reason for using member routes, because I personally find it easier to remember the name of the route helper.

Now if you want to generate a path for liking and disliking a post or a comment, you will have to check if the likable is a post or a comment to generate the right path for it.

# paths for liking or disliking a post
link_to 'like', like_post_path(@post), method: :post
link_to 'dislike', dislike_post_path(@post), method: :delete
# paths for liking or disliking a comment
link_to 'like', like_comment_path(@post), method: :post
link_to 'dislike', dislike_comment_path(@post), method: :delete

But with using polymorphic_path, this can be refactored into:

link_to 'like', polymorphic_path([:like, @likable]), method: :post
link_to 'dislike', polymorphic_path([:dislike, @likable]), method: :delete

In this case, polymorphic_path generates the right URL based on the @likable type.

This can be very handy working with a rails gems, when you don't know the @likable type.


© 2020 Muhammad Ebeid. This site is powered by Netlify