I'm having a little brain block when it comes to condensing the use of two #find
methods in ActiveRecord down to a single statement and SQL query.
I have a Sinatra route where the slug of both a parent and child record are supplied (the parent has many children). Atm I'm first finding the parent with a #find_by_slug
call and then the child by #find_by_slug
again on the matched parents association.
This results in two SQL queries that in my mind should be able to be condensed down to one easily... Only I can't work out how that's achieved with ActiveRecord.
Model, route and AR log below. Using ActiveRecord 3.2
I realised I need to clarify the exact outcome to require (I write this very late in the day). I only require the Episode
but atm I'm getting the Show
first in-order to get to the Episode
. I only require the Episode
and figured their must be a way to get at that object without adding the extra line and getting the Show
first.
class Show < ActiveRecord::Base
has_many :episodes
end
class Episode < ActiveRecord::Base
belongs_to :show
end
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
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
If you only need the @episode
, you can maybe do
@episode = Episode.joins(:shows).where('shows.slug = ?', show_slug).where('episodes.slug = ?', episode_slug).first
If you also need @show
, you've got to have two queries.