Reputation: 1895
I have three tables, Show
, Episode
, and Character
. Each Show has_many Episodes and Characters.
class Show < ActiveRecord::Base
has_many :episodes
has_many :characters
class Episode < ActiveRecord::Base
belongs_to :show
class Character < ActiveRecord::Base
belongs_to :show
Episode has the attributes :air_date
and :episode_number
. Show has an attribute :title
.
I have a list of Characters @characters
. What I want to accomplish is to print a list of the Shows associated with those Characters, ordered by the air date of the Show's second Episode.
<% @characters.includes(show: :episodes).where(episodes: {episode_number: 2}).order('episodes.air_date DESC').each do |character| %>
<%= character.show.title %>
<% end %>
This almost works, but some Shows have multiple characters, so in the printed list, some Shows are listed multiple times.
Is it possible to apply the ruby method uniq
to the Shows table in my query, so that each Show is printed a maximum of one time?
Upvotes: 0
Views: 45
Reputation: 79
One thing I usually do in your case, is that I look at what I want to accomplish in SQL, write it out, test that it works, then translate it to ActiveRecord or in some cases keep it as a custom SQL query using find_by_sql
So here is what you want to accomplish in SQL:
Show.find_by_sql(<<-SQL, character_ids_array)
SELECT
DISTINCT ON (shows.id) shows.*
FROM
characters
JOIN
shows on characters.show_id = shows.id
JOIN
episodes on shows.id = episodes.show_id
WHERE
characters.id IN #{character_ids_array} AND epsiodes.epsiode_number = 2
ORDER BY
episodes.air_date DESC
SQL
This is unrelated to your main question, but I would suggest doing your logic in the Controller not in ERB. For the sake of convention :)
Also, make sure when you translate to ActiveRecord your query is cashed all the way to the end to avoid N+1 queries.
Upvotes: 0
Reputation: 3899
What about a group by?
<% @characters.includes(show: :episodes).where(episodes: {episode_number: 2}).order('episodes.air_date DESC').group_by(&:show).each do |show, characters|
<%= show.title %>
<% end %>
Upvotes: 1