1

我有 3 张桌子需要连接在一起。

我有Events,PlacesBoroughs

地方属于自治市镇并有许多活动

从给定日期的事件列表中,我想检索所有不同行政区的列表。

Event.where(day_of_week: 2).joins(:place,:borough).select("DISTINCT(boroughs.name) AS name")

生成 SQL:

SELECT DISTINCT(boroughs.name) AS name FROM "events" INNER JOIN "places" ON "places"."id" =        
"events"."place_id" INNER JOIN "places" "places_events_join" ON "places_events_join"."id" = 
"events"."place_id" INNER JOIN "boroughs" ON "boroughs"."id" = 
"places_events_join"."borough_id" WHERE "events"."active" = 't' AND "events"."day_of_week" = 3

当我将它放入我的 postgres DB 控制台时,它看起来很完美并且可以工作,但是对于我的 rails 控制台,我得到了。

#<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >

更新:

Mr.The Walrus 的建议非常有效,但我仍然很困惑,为什么当 SQL 本身产生相同的结果时,反过来却行不通。

Borough.joins(:events).where(:events => {:day_of_week => 2}).select("DISTINCT(boroughs.name) AS name")

产生:

[#<Borough name: "richmond">, #<Borough name: "southwark">, #<Borough name: "brent">, #<Borough name: "city of london">] 

但是这个

Event.where(:events => {:day_of_week => 2}).joins(:borough).select("DISTINCT(boroughs.name) AS name")

产生:

[#<Event >, #<Event >, #<Event >, #<Event >, #<Event >] 
4

4 回答 4

3

您需要为您的列命名,否则 ActiveRecord 将不知道如何映射它。

Event.where(day_of_week: 2).joins(:place,:borough).select('DISTINCT(boroughs.name) as "bouroughs.name"')
于 2013-02-22T20:23:59.920 回答
2

我想我会这样做:

Borough.joins(:events).where(:events => {:day_of_week => 2})

默认情况下,Rails 将使用内部连接,因此它将排除任何没有匹配事件的自治市镇。如上所述,您实际上根本不需要用于查询的位置数据。

于 2013-02-22T20:31:27.030 回答
2

从 Rails 3.2 开始,尝试Pluck

Event.where(:events => {:day_of_week => 2}).joins(:borough).uniq.pluck('boroughs.name')

应该管用。

如果您打算将其与预先警告的范围链接起来,延迟加载将导致它无法按预期工作,而是执行类似的操作

def self.somemethod
  joins(:borough).pluck('boroughs.name').uniq
end
于 2013-02-23T12:24:16.917 回答
1

首先,别名列名,

select("DISTINCT boroughs.name as borough_name")

然后将该名称作为字段访问。

events = Event.where(day_of_week: 2).joins(:place,:borough).select("DISTINCT boroughs.name as borough_name")
events.map{|event| event.borough_name}
于 2013-02-22T20:27:34.423 回答