Have you ever struggled with polymorphic associations? We all have, don’t worry.
Here’s an example of a polymorphic relationship.
class Picture < ApplicationRecord | |
belongs_to :imageable, polymorphic: true | |
end | |
class Employee < ApplicationRecord | |
has_many :pictures, as: :imageable | |
end | |
class Product < ApplicationRecord | |
has_many :pictures, as: :imageable | |
end |
I’ve recently bumped into a problem where I had to list out all subjects (employees and products in this case) and when user interacted with one list item, it would redirect to that subject’s show page.
<table> | |
<thead> | |
<tr> | |
<th>Name</th> | |
</tr> | |
</thead> | |
<tbody> | |
<% @imageable.each do |imageable| %> | |
<tr> | |
<td> | |
<%= link_to imageable.name, ?????? %> | |
</td> | |
</tr> | |
<% end %> | |
</tbody> | |
</table> |
You can see the problem, right? The obvious solution here would be to check the type of imageable and set the path helper accordingly. But, there’s a slightly more advanced technique for this use-case: direct method.
In your routes.rb file simply add this:
direct(:imageable) { |imageable| route_for ("#{imageable.class.name.underscore}".to_sym, imageable) } |
And now you can use imageable_path(imageable) as a path helper that will dynamically resolve to imageable’s show page.
Now our example above becomes:
<table> | |
<thead> | |
<tr> | |
<th>Name</th> | |
</tr> | |
</thead> | |
<tbody> | |
<% @imageable.each do |imageable| %> | |
<tr> | |
<td> | |
<%= link_to imageable.name, imageable_path(imageable) %> | |
</td> | |
</tr> | |
<% end %> | |
</tbody> | |
</table> |
Aaaand voilà, we’ve got a path helper that resolves to any imageable show page without the need to manually check for the type of imageable.
Top comments (0)