29 February 2016 · About 1 minute read

Rails: Generating Polymorphic URLs when Model name does not match Route

Given a slugged generic model for which you want to generate a URL at runtime, you can usually just call:

@b = BlogPost.find(params[:id])
# ==> BlogPost[id: 100, slug: "hello-world"]

# ==> blog_post_url(b.id)
# ==> "/blog_posts/hello-world"

However, I recently came across a case where the named route did not match the model name. Using the above as an example:

# config/routes.rb
resources :blog_posts, as: 'posts'

Unfortunately, calling polymorphic_path now throws an error complaining that the generated path method (blog_post_url) does not exist. The path name, which is inferred through the model class BlogPost no longer matches any routes.

Instead, we needed the method to be post_url.

Thankfully, polymorphic_url lets you supply the path as a symbol, rather than inferring it from the model. We can then pass the additional information (in this case, the slug parameter) to the helper as an argument:

polymorphic_url([b.model_name.human.underscore.to_sym], id: b.slug)

==> post_url(b.id)
==> "/posts/hello-world"
Chris Blunt
Chris Blunt @cblunt
Chris is the founder of Plymouth Software. As well as code and business, he enjoys being a Dad, swimming, and the fine art of drinking tea.