Within a rails .each
code, how can I eliminate duplicates from the result?
PMRelationships is a relationship table that links people and movies
MGRelationships is a relationship table that links genres and movies
The process Im looking for is to find All a Person's genres through first PmRelationship then MgRelationship
<% @pm_relationships = PmRelationship.where(:people_id => @person.id) %>
<ul class="basic-info-genres">
<% @pm_relationships.each do |pm_relationship| %>
<% @movie=Movie.find(pm_relationship.movie_id) %>
<% @mg_relationships = MgRelationship.where(:movie_id => @movie.id) %>
<% @mg_relationships.each do |mg_relationship| %>
<% @genre=Genre.find(mg_relationship.genre_id) %>
<%= @genre.name %>
<% end %>
<% end %>
</ul>
For example, this code returns a list of values, as such:
Action
Action
Comedy
Thriller
Adventure
Noir
Action
How can I make it so that It removes the two Lorems and only show one
Basically, Get rid of any duplication to return a list as such
Action
Comedy
Thriller
Adventure
Noir
UPDATE
I've changed my simplified code to match that of my actual app
I am aware most of this needs to be in the controller but simplified sake I'm doing it in the views first
Side note to those who could mention that I needn't create _Relationship tables and could simply use models has_many_belongs_to etc.., I find the Relationship table method much easier to handle and control
Thanks and apologies for the confusion
As you are aware that your can use associations
, I highly recommend it. It will help you to clean up the code and will save database queries.
Another thing, you are missing <li></li>
inside <ul></ul>
.
Anyways, as per your current code, you can just populate your all @genre.name
in a Set
# as you said in question, following code should be moved to controller
genre_names = Set.new
<% @pm_relationships = PmRelationship.where(:people_id => @person.id) %>
<% @pm_relationships.each do |pm_relationship| %>
<% @movie=Movie.find(pm_relationship.movie_id) %>
<% @mg_relationships = MgRelationship.where(:movie_id => @movie.id) %>
<% @mg_relationships.each do |mg_relationship| %>
<% @genre=Genre.find(mg_relationship.genre_id) %>
<% genre_names.add(@genre.name) %>
<% end %>
<% end%>
# actual view code
<ul class="basic-info-genres">
<%= "<li>#{genre_names.to_a.join('</li><li>')}</li>".html_safe %>
</ul>
May be you want to read more about Set
NOTE: After moving code to corresponding files, use appropriate variable types in controller and view, as required
Try to replace your original code:
<% @mg_relationships.each do |mg_relationship| %>
<% @genre=Genre.find(mg_relationship.genre_id) %>
<%= @genre.name %>
<% end %>
To:(this version did not broken your code structure, just change the position of the output code)
<% genre_names = []%>
<% @mg_relationships.each do |mg_relationship| %>
<% @genre=Genre.find(mg_relationship.genre_id) %>
<%#= @genre.name %>
<% genre_names |= [@genre.name]%>
<% end %>
<%= genre_names %> or <%= genre_names.join(" ") %>
Using the uniq
method on Array
, you'll be able to remove duplicates.
See here for reference: http://www.ruby-doc.org/core-2.1.2/Array.html#method-i-uniq
<% @worlds.collect(&:latin).uniq.each do |latin| %>
<%= latin.name %>
<% end %>
This assumes there's a belongs_to association between World and Latin (I assumed this because of the World#latin_id field and the fact there's a model called Latin).
EDIT: if you have multiple Latin objects with the same name then collect the names then do uniq
:
<% @worlds.collect(&:latin).collect(&:name).uniq.each do |name| %>
<%= name %>
<% end %>
you can try this to get uniq latin name
<% @worlds.collect(&:latin).collect(&:name).uniq.each do |latin_name| %>
<%= latin_name %>
<% end %>