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"]

polymorphic_url(b)  
# ==> 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"