Last active
April 5, 2024 16:00
-
-
Save mildmojo/3724189 to your computer and use it in GitHub Desktop.
LEFT JOIN in ARel for ActiveRecord in Ruby on Rails
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Here's a contrived example of a LEFT JOIN using ARel. This is an example of | |
# the mechanics, not a real-world use case. | |
# NOTE: In the gist comments, @ozydingo linked their general-purpose ActiveRecord | |
# extension that works for any named association. That's what I really wanted! | |
# Go use that! Go: https://gist.github.com/ozydingo/70de96ad57ab69003446 | |
# == DEFINITIONS | |
# - A Taxi is a car for hire. A taxi has_many :passengers. | |
# - A Passenger records one person riding in one taxi one time. It belongs_to :taxi. | |
class Taxi < ActiveRecord::Base | |
# This scope LEFT JOINs the Passenger table. You might use this if you wanted | |
# to select taxis by a set of taxi and passenger IDs (as with the | |
# SQL "taxis.id IN () OR passengers.id IN ()"). | |
def self.left_join_passengers | |
taxis = Taxi.arel_table | |
passengers = Passenger.arel_table | |
# The key here is providing the join type (Arel::Nodes::OuterJoin) and | |
# grabbing the ARel join object itself from Arel::SelectManager#join_sources | |
# to feed to ActiveRecord's #joins method. | |
# SQL equivalent: "LEFT OUTER JOIN passengers ON taxis.id = passengers.taxi_id" | |
taxi_passengers = taxis.join(passengers, Arel::Nodes::OuterJoin). | |
on(taxis[:id].eq(passengers[:taxi_id])). | |
join_sources | |
joins(taxi_passengers) | |
end | |
end | |
# Sources that almost documented this: | |
# http://blog.donwilson.net/2011/11/constructing-a-less-than-simple-query-with-rails-and-arel/ |
Can we further join taxi_passengers
with another table ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks!