2012-07-02 34 views
1

我看过类似的问题,但没有找到与我需要的答案完全匹配的答案。如果它在外面,我还没有看到它。我on Rails的3.1,红宝石1.9.2,部署在Heroku上雪松堆栈(所以我使用的是Postgres)RoR/Postgres查询所有父母的第一个或最后一个子对象

我有了这个模型:

class User 
    has_many :orders 
end 

class Order 
    belongs_to :user 

    #scope :last_for_each_user, ??? 
    #scope :first_for_each_user, ??? 

end 

我需要的范围(或方法)返回所有用户的第一个订单的所有订单,以及所有用户的最后一个订单的所有订单。我的第一个直觉是使用GROUP BY,它在SQLite3中的last_for_each_user上工作正常,但Postgres不会让你选择不在GROUP BY子句中或作为聚合函数的一部分选择的列,而且我需要完全形成的命令对象(即所有的列,命令。*)。

任何想法?我不想选择整个表并在Ruby中对其进行排序。这只是感觉不对,而且要记住很多东西。

回答

1

所以这里就是我最后做,为未来的头刮管:

scope :last_for_each_user, lambda { 
    select("orders.*") & Order.select("max(orders.id) as id").group("orders.user_id") 
} 
scope :first_for_each_user, lambda { 
    select("orders.*") & Order.select("min(orders.id) as id").group("orders.user_id") 
} 

如果任何人有一个更好的主意,我非常开放的听到它。感谢整个SO社区(尽管没有人回应),这是我第一次注册/问一个问题,但每次我在谷歌的一个问题,我最终在这里!

+0

什么'Order.where(ID:Order.select( “分钟(orders.id)的ID”)组( “orders.user_id”)。)'? – cbliard

0

您可以使用DISTINCT ON()规则只获取最后一个。下面是一个例子如下模型结构:

scope :for_users, lambda {|ids, is_first| includes(:user).where("user_id IN (?)", ids).select("DISTINCT ON (users.id) *").order("orders.created_at ?", is_first ? : "ASC" : "DESC") } 
scope :last_for_each_users, lambda { |users| for_each_users(users.map{|u| u.id }, false } 
scope :first_for_each_users, lambda { |users| for_each_users(users.map{|u| u.id }, true } 
相关问题