Squeel для выполнения внешнего соединения на Rails - PullRequest
3 голосов
/ 17 января 2012

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

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

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

City
Building
CityBuilding

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

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

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

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

Ответы [ 2 ]

5 голосов
/ 01 февраля 2012

Я думаю, что вы можете попробовать что-то вроде ниже, используя 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 голосов
/ 28 января 2012

AR-ассоциация 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")

Примечание

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

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

...