2015-11-05 67 views
0

我有三个表,Show,EpisodeCharacter。每个显示has_many节目和字符。在嵌套连接表上调用uniq

class Show < ActiveRecord::Base 
    has_many :episodes 
    has_many :characters 

class Episode < ActiveRecord::Base 
    belongs_to :show 

class Character < ActiveRecord::Base 
    belongs_to :show 

情节有属性:air_date:episode_number。显示有一个属性:title

我有一个字符列表@characters。我想要完成的是打印与这些角色相关的节目列表,由节目第二集的播出日期排序。

<% @characters.includes(show: :episodes).where(episodes: {episode_number: 2}).order('episodes.air_date DESC').each do |character| %> 
    <%= character.show.title %> 
<% end %> 

这几乎工作,但一些节目有多个字符,所以在打印列表中,一些节目被多次列出。

是否有可能将红宝石方法uniq应用于查询中的Shows表,以便每个Show最多打印一次?

回答

1

一群人怎么样?

<% @characters.includes(show: :episodes).where(episodes: {episode_number: 2}).order('episodes.air_date DESC').group_by(&:show).each do |show, characters| 
    <%= show.title %> 
<% end %> 
0

有一件事我通常会做你的情况是,我看什么,我要在SQL中完成,写出来,测试它的效果,然后将其转化为ActiveRecord的或在某些情况下保持它作为使用find_by_sql

所以在这里自定义SQL查询你想要什么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 

这无关你的主要问题,但我会建议在控制器不这样做你的逻辑在ERB。为了约定:)

此外,请确保当您翻译为ActiveRecord时,您的查询将兑现至最后以避免N + 1个查询。