在嵌套连接表上调用uniq

时间:2015-11-05 20:32:27

标签: mysql sql ruby-on-rails ruby uniq

我有三个表,ShowEpisodeCharacter。每个节目都有很多剧集和角色。

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的属性为: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表,以便每个Show最多打印一次?

2 个答案:

答案 0 :(得分: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 %>

答案 1 :(得分:0)

我通常在你的情况下做的一件事是,我看看我想在SQL中完成什么,写出来,测试它是否有效,然后将其转换为ActiveRecord,或者在某些情况下将其保存为自定义SQL查询使用find_by_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个查询。