在嵌套连接上调用 uniq table

Calling uniq on a nested joins table

我有三个 table,ShowEpisodeCharacter。每个节目 has_many 集和角色。

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。 Show 有一个属性 :title.

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

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

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

是否可以将 ruby 方法 uniq 应用于我查询中的 Shows table,以便每个 Show 最多打印一次?

分组依据如何?

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

对于你的情况,我通常会做的一件事是,我会查看我想在 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

这与您的主要问题无关,但我建议您在 Controller 而不是 ERB 中执行您的逻辑。为了约定:)

此外,请确保当您转换为 ActiveRecord 时,您的查询一直兑现到最后以避免 N+1 查询。