简化对ActiveRecord的多次调用#find向下到单行/ SQL语句

时间:2013-05-29 23:55:42

标签: ruby activerecord sinatra arel

当涉及将ActiveRecord中两个#find方法的使用压缩为单个语句和SQL查询时,我有一点脑力。

我有一条Sinatra路线,其中提供了父母和子记录的子弹(父母有很多孩子)。 Atm我首先在#find_by_slug电话上找到父母,然后在匹配的父母协会上再次通过#find_by_slug找到孩子。

这导致两个SQL查询在我看来应该可以简单地压缩到一个...只有我无法弄清楚如何用ActiveRecord实现。

下面的型号,路线和AR日志。使用ActiveRecord 3.2

修改

我意识到我需要澄清要求的确切结果(我在当天很晚才写出来)。我只需要Episode,但我首先按Show获取Episode。我只需要Episode并认为他们必须是一种获取该对象的方法,而无需添加额外的行并首先获得Show

模型

class Show < ActiveRecord::Base
  has_many :episodes
end

class Episode < ActiveRecord::Base
  belongs_to :show
end

Sinatra路线

get "/:show_slug/:episode_slug" do
  @show = Show.find_by_slug show_slug
  @episode = @show.episodes.find_by_slug episode_slug

  render_template :"show/show"
end

ActiveRecord日志

Show Load (1.0ms)  SELECT `shows`.* FROM `shows` WHERE `shows`.`slug` = 'the-show-slug' LIMIT 1
Episode Load (1.0ms)  SELECT `show_episodes`.* FROM `show_episodes` WHERE `show_episodes`.`show_id` = 1 AND `show_episodes`.`slug` = 'episode-21' LIMIT 1

1 个答案:

答案 0 :(得分:1)

如果您只需要@episode,则可以

@episode = Episode.joins(:shows).where('shows.slug = ?', show_slug).where('episodes.slug = ?', episode_slug).first

如果您还需要@show,则必须提出两个问题。