Question

I'm trying to find a way to create a simple outer join without too much hassle. I know I can do this manually by specifying an outer join, but I'm looking for a simple way.

Therefore, I was taking a look at Squeel, which seems to be the new alternative for Metawhere. It seems to be able to handle outer joins, but I can't get what I want.

In particular, I have three models :

City
Building
CityBuilding

I would simply like a list of all the buildings whether they exist in a city or not. CityBuilding is, of course, the model that connects a city to a building. I would like to get something like :

city 1{
  TownCenter => city_building
  Sawmill => city_building
  Quarry => nil
} 

The query is null since there is no city_building entry for this one, you get the idea.

Is there a way that Squeel does that? Or maybe another gem, without having to manually do an outer join?

Was it helpful?

Solution

I think you can try something like the below using Squeel. I am not sure about the where part. You will have to give one of the two join conditions.

Building.joins{city}.joins(city_buildings.outer).where{(buidlings.id == city_buildings.building_id) & (cities.id == city_buildings.city_id)}

or

Building.joins{city}.joins(city_buildings.outer).where{buidlings.id == city_buildings.building_id}

or

Building.joins{city}.joins(city_buildings.outer).where{cities.id == city_buildings.city_id}

OTHER TIPS

The AR association includes uses LEFT OUTER JOIN. If you have a model relationship as follows, then:

class City
  has_many :city_buildings
  has_many :buildings, :through => :city_buildings
end

class Building
  has_one :city_building
  has_one :city, :through => :city_building
end

class CityBuilding
  belongs_to :city
  belongs_to :building
end

To get a list of buildings regardless of city link

Building.includes(:city).where(...)

To get a list of buildings with a of city link

Building.includes(:city).where("cities.id IS NOT NULL")

Note

I am assuming you want to access the city object after the query(if present).

This is not a good solution if you DO NOT want to eager load the city object associated with a building (as AR eager loads include associations after executing the OUTER JOIN).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top