According to https://www.w3schools.com/sql/sql_join.asp there are four types of joins in SQL. In fact there is also self-join and cross join but lets focus on: INNER JOIN, LEFT (OUTER) JOIN, RIGHT (OUTER) JOIN, FULL (OUTER) JOIN.
Assume that we have following factories:
1 2 3 4 5 6 7 8
let!(:user_1) { create(:user)} # user with 2 trips let!(:user_2) { create(:user)} # user with 1 trip let!(:user_3) { create(:user)} # user with no trips
let!(:trip_1) { create(:trip, user: user_1) } let!(:trip_2) { create(:trip, user: user_1) } let!(:trip_3) { create(:trip, user: user_2) } let!(:trip_4) { create(:trip, user:nil) } # trip with no user
1. INNER JOIN
1 2 3 4 5 6 7 8 9 10 11 12 13 14
inner_join = User.joins(:trips) puts inner_join.to_sql # => SELECT "users".* FROM "users" INNER JOIN "trips" ON "trips"."user_id" = "users"."id"
expect(inner_join.count).to eq(3)
inner_join.each do|user| puts [user.id, user.trips.pluck(:id)].inspect end
Keep in mind that you should use .distinct at the end of the query chain to get unique rows.
2. LEFT (OUTER) JOIN
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
left_outer_join = User.left_outer_joins(:trips) # or simply use an alias: left_joins puts left_outer_join.to_sql # => SELECT "users".* FROM "users" LEFT OUTER JOIN "trips" ON "trips"."user_id" = "users"."id"
expect(left_outer_join.count).to eq(4)
left_outer_join.each do|user| puts [user.id, user.trips.pluck(:id)].inspect end