Jac*_*ham 5 activerecord ruby-on-rails
我有一个带有parent_id和date属性的事件模型:
Event.rb
has_many :children, :class_name => "Event"
belongs_to :parent, :class_name => "Event"
Run Code Online (Sandbox Code Playgroud)
我没有问题event.parent或event.children.儿童事件本身从未有过孩子.
我正在尝试为此模型添加一个范围,以便我可以为每个父项返回最近的日期.就像是:
scope :future, -> {
where("date > ?", Date.today)
}
scope :closest, -> {
group('"parent_id"').having('date = MAX(date)')
}
Event.future.closest ==> returns the closest child event from every parent
Run Code Online (Sandbox Code Playgroud)
但上述:closest范围是每个父母返回一个以上的孩子.
暂时忽略 Rails,您在 SQL 中所做的事情是最大的每组问题。这里有很多解决方案。我会选择DISTINCT ON或LEFT OUTER JOIN LATERAL。它在 Rails 中的外观如下:
scope :closest, -> {
select("DISTINCT ON (parent_id) events.*").
order("parent_id, date ASC")
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供子对象。(您可能还需要一个条件来排除没有 的行parent_id。)从您自己的解决方案来看,听起来这就是您想要的。相反,如果您想要父对象以及可选的附加子对象,则使用横向连接。不过,将其转换为 ActiveRecord 有点棘手。如果可以接受在两个查询中执行此操作,那么看起来它应该可以工作(坚持使用DISTINCT ON):
has_one :closest_child, -> {
select("DISTINCT ON (parent_id) events.*").
order("parent_id, date ASC")
}, class_name: Event, foreign_key: "parent_id"
Run Code Online (Sandbox Code Playgroud)
那么你可以说Event.includes(:closest_child)。同样,您可能想过滤掉所有非父母。
| 归档时间: |
|
| 查看次数: |
616 次 |
| 最近记录: |