2012-01-17 1 views
3

Я пытаюсь найти способ создать простое внешнее соединение без лишних хлопот. Я знаю, что могу сделать это вручную, указав внешнее соединение, но я ищу простой способ.Squeel для выполнения внешнего соединения на Rails

Поэтому я взглянул на Squeel, который, кажется, является новой альтернативой для Metawhere. Кажется, он способен обрабатывать внешние соединения, но я не могу получить то, что хочу.

В частности, у меня есть три модели:

City 
Building 
CityBuilding 

Я бы просто как список всех зданий, существуют ли они в городе или нет. CityBuilding - это, конечно же, модель, соединяющая город с зданием. Я хотел бы получить что-то вроде:

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

Запроса является нулевым, так как нет city_building записи для этого, вы получите идею.

Есть ли способ, которым Squeel это делает? Или, может быть, другой драгоценный камень, без необходимости вручную выполнять внешнее соединение?

+0

"все здания, существуют ли они в городе или нет" ... это не то, что 'Building.find (: все) '? – rkb

+0

, пожалуйста, перечитайте вопрос, это не то, о чем я прошу. – Spyros

ответ

5

Я думаю, что вы можете попробовать что-то вроде ниже, используя Squeel. Я не уверен в том, где часть. Вам нужно будет дать одно из двух условий соединения.

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

или

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

или

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

Ассоциация АР includes использует LEFT OUTER JOIN. Если у вас есть отношения модели следующим образом, то:

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 

Чтобы получить список зданий, независимо от города ссылки

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

Чтобы получить список зданий с городской линии

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

Примечание

Я предполагаю, вы хотите получить доступ к объекту города после запроса (если имеется).

Это нехорошее решение, если вы НЕ хотите загружать объект города, связанный со зданием (так как AR-загруженные нагрузки включают ассоциации после выполнения OUTER JOIN).