Lets say I have a wine and beer model/controller along with a wine_review and beer_review model with a has many relationship.
Each table has near identical data types, for example, wine_review and beer_review each has a rating and comment column.
Wine and beer each, have names.
How can I dry up my code so they can both share the same views.
Right now I have two views doing the same thing, once for beer and once for wine.
<% @wine_reviews.each do |review| -%>
<ul>
<li><%= link_to review.wine.name, review.wine %></li>
<li><%= review.rating %></li>
<li><%=h review.comment %></li>
</ul>
<% end -%>
<% @beer_reviews.each do |review| -%>
<ul>
....
....
What I would really like to do is something like
<li><%= link_to review.beverage.name, review.beverage %></li>
Where beverage would be replaced with wine or beer depending on what I’m rendering at that time but I can’t figure out how to do that.
I can’t pass beverage as a local to a partial as review.beverge will break.
Thanks.
You have several different options here:
Duck typing:
In Ruby, as long as an object responds to a method call that method call with work. So if both beer and wine have an attribute :name, then calling @result.name will work with either model.
Polymorphic Associations:
Instead of having review.beer or review.wine. Make Wine and Beer reviewable via a polymorphic association. This will also work for comments, e.g., both become commentable. Take a look at acts_as_commentable for how this works. Railscasts has an excellent screencast on how this works.
Single Table Inheritance:
You could create an object called Beverage from which Wine and Beer inherit. This allows for a single place to put the similar attributes and still allows for small differences.
From your description, you are looking at a combination of all three possibly.