Squeel在Rails上执行外连接

时间:2012-01-17 03:20:45

标签: ruby-on-rails ruby-on-rails-3 squeel

我试图找到一种方法来创建一个简单的外连接而不会有太多麻烦。我知道我可以通过指定外连接手动完成此操作,但我正在寻找一种简单的方法。

因此,我正在看看Squeel,这似乎是Metawhere的新选择。它似乎能够处理外连接,但我无法得到我想要的东西。

特别是,我有三种模式:

City
Building
CityBuilding

我想简单地列出所有建筑物是否存在于城市中。当然,城市建筑是将城市与建筑连接起来的模型。我想得到类似的东西:

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

查询为空,因为此条目没有city_building条目,您就明白了。

Squeel有没有办法做到这一点?或者可能是另一个宝石,而不必手动进行外连接?

2 个答案:

答案 0 :(得分: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}

答案 1 :(得分:2)

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")

注意

我假设你想在查询后访问城市对象(如果存在)。

如果您不想急于加载与建筑物相关联的城市对象,那么这不是一个好的解决方案(因为AR急切加载包括执行OUTER JOIN后的关联)。