@etravassos had mentioned wanting to find Arel alias names, and it reminded me of something I’ve been keeping under my hat for awhile… had put a thing in The Brick about a year ago that greatly simplifies how we can query ActiveRecord. Have now battle-tested it enough that it’s time to make an announcement.
Imagine you have these three tables:
Say you would like to get a list of flights and include some detail about their departure and arrival airports. For both departures and arrivals, you want to show the airport code and city name. Because this requires these 4 JOINs:
Flight.joins(departure: :city, arrival: :city)
and also since you can’t easily predict the alias names that will get chosen for each of those four, normally you would need to first see what the resulting SQL would be. And then from this you can find the alias (correlation) names for airports and cities.
After investigating this resulting SQL, you would discover that the first time airports is JOINed in, it is called just that, and the second time, it gets called arrival_flights for whatever reason (even though it really is the airports table, and just JOINed another time). Similar for cities – first time when JOINed for departure airport it is just cities, and the second time JOINed to find the arrival city, it gets called cities_airports. Knowing this, you could write this final query:
3.3.0 :004 > Flight.joins(departure: :city, arrival: :city)
.pluck(:dt, 'airports.code AS departure_code',
'cities.name AS departure_city',
'arrivals_flights.code AS arrival_code',
'cities_airports.name AS arrival_city')
=>
[[Wed, 27 Mar 2024, "LHR", "London", "BCN", "Barcelona"],
[Fri, 29 Mar 2024, "AMS", "Amsterdam", "CDG", "Paris"]]
3.3.0 :005 >
This is all a bit brittle. What if (God forbid) Arel were to change the way that it assigns correlation names? I mean, it probably won’t because so many people have now hard-coded these alias names in place in this kind of way, so there would be a full-on uprising if it started working differently. Then everyone would have to change those Arel-ish names around that they’d put into the .select()
and .where()
and .pluck()
parts of their AR queries. Balderdash!
So imagine if you could write something like this instead, not using any of those weird hard-coded correlation names. Not even having to separately say what associations you’re JOINing across…
Flight.brick_pluck(:dt, 'departure.code', 'departure.city.name',
'arrival.code', 'arrival.city.name')
… almost looks like pseudocode, doesn’t it? But it’s real! Just put The Brick gem into your project, and you too can enjoy this kind of simpler querying. Across any level of complexity of belongs_to
and has_many
that you want. Throw it the works. See if it can take it. You can use both brick_select
and brick_pluck
– they both work in this kind of way. And there’s also brick_where
that I’ll document a bit better later. But for now it’s 2:30am here in UK, so I need to rest.
Welcome to the magic of The Brick!