关于activerecord:rails独立地对has_many对象进行查询联接

 2019-10-09 

rails joins query over has_many objects independently

我有父模型Project和子模型ToDo

一个项目有许多ToDosstarts_atends_at

我想搜索在该时间范围内有"任何"待办事项的项目。

在这里我写了一些代码,但是,这与预期的不一样。

1
2
3
4
5
6
7
class Project
   has_many :todos

   scope :active, -> {joins(:todos).where("todos.starts_at < '#{Time.now}' AND todos.ends_at > '#{Time.now}'").distinct}
   scope :waiting, -> {joins(:todos).where.not("todos.starts_at < '#{Time.now}' AND todos.ends_at > '#{Time.now}'").distinct}
   scope :done, -> {where("project_due > ?", Time.now)}
end

主动活动似乎是正确的,但是等待范围还包含具有多个待办事项的项目。

我想知道是否有解决方案可以比较每个待办事项的starts_atends_at。 不像上面。

谢谢你

*#更新*

这就是我想要实现的。 但是在一个查询中

1
scope :waiting, -> { joins(:todos).where.not(id: active.ids).where('finishing > ?', Time.now).distinct }


您的等待查询基本上从!(start < now && end > now)转换为start >= now || end <= now,这很可能返回比您想要的项目更多的项目。看看这是否是您想要的逻辑。

另外,为了获得最佳的Rails做法,您应该使用问号编写查询,如其他答案中建议的用户fool-dev一样。这是为了防止SQL注入,如此处详细说明

编辑
因此,我认为您的意思是等待是指没有任何待办事项或等待待办事项(start_at > now)的项目。我认为这应该工作:

1
scope(:waiting) { includes(:todos).where('todos.project_id IS NULL OR todos.start_at > ?', Time.now).distinct }

第一部分是选择没有任何待办事项的项目,第二部分是不言自明的。


尝试以下

更新资料

等待是指starts_at大于NOW对吗?那将会是

1
scope :waiting, -> {joins(:todos).where("todos.starts_at >= ?", Time.now).distinct}

如果与第一个条件匹配,那么您就不需要与第二个条件匹配,则可以使用第二个条件进行编写,如下所示

1
scope :waiting, -> {joins(:todos).where("todos.starts_at > '#{Time.now}' AND todos.ends_at > '#{Time.now}'").distinct}

但不需要

更新2

where中删除not,此处not表示active

1
scope :waiting, -> {joins(:todos).where("todos.starts_at >= ?", Time.now).distinct}

更新2生效后的更新3

1
2
3
scope :waiting, -> {joins(:todos).where("todos.starts_at >= ?", Time.now).distinct}
scope :finished, -> {where("finishing > ?", Time.now).distinct}
scope :waiting_n_progress, -> {where.not(id: active.ids).finished.waiting}

waiting_n_progress范围,我想您会实现目标的,请记住这未经测试。

希望它能工作。