2011-08-03 86 views
4

我有一個將用戶連接到帖子的作用域,以便僅獲取具有可見帖子的用戶。這在MySQL中有效,但PG更嚴格,並且引發錯誤。Rails/Postgres:列必須出現在GROUP BY子句中

用戶模型:

belongs_to :account 

scope :have_posts, joins(:posts).where('posts.visible => true').group('users.id') 

控制器:

@account.users.have_posts.each do |user| 
    # do stuff 
end 

錯誤:

(PGError: ERROR: column "users.account_id" must appear in the GROUP BY clause or be used in an aggregate function: SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE ("users".account_id = 1) AND (recommendations.approved = true) GROUP BY users.id)

它抱怨 「users.account_id」,這是從調用@account.users(我明明唐不希望數據庫中的所有用戶)。

任何想法如何解決?

回答

6

問題是GROUP BY子句。如果您使用此選項,則無法選擇任何非聚合字段,因此SELECT "users".* [...]不起作用。從Postgres的文檔:

In general, if a table is grouped, columns that are not used in the grouping cannot be referenced except in aggregate expressions.

像這樣的東西可能工作,雖然凌亂:

一個替代方案是每一個選定字段使用聚合功能,如MAXMIN指定,但是這可能會令範圍更大,功能更少。

0

這應該表示爲where條件不是joins,因爲不需要任何來自posts的數據。恕我直言更容易閱讀:

scope :have_posts, -> { 
    where(
    'EXISTS (SELECT 1 FROM posts p WHERE p.id = users.id AND visible = true)' 
) 
} 

Ruby 2和Rails 3/4準備好了。 PG優化器將盡可能快地運行它。

相關問題