rails独立地加入对has_many对象的查询

时间:2018-03-25 06:28:09

标签: ruby-on-rails activerecord

我有父模型Project&儿童模型ToDo

项目有许多ToDos,其中包含starts_at列& ends_at

我想搜索那些有任何'的项目。在时间范围内的待机。

在这里,我写了一些代码,然而,它并不像预期的那样。

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_at&amp;每个待办事项ends_at。不像以上那样。

非常感谢。

* #Update *

这就是我想要达到的目标。但在一个查询中。

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

2 个答案:

答案 0 :(得分:1)

尝试以下

<强>更新

等待你的意思是starts_at大于NOW对吗?那么它将是

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

如果匹配第一个条件,那么你不需要匹配第二个条件,你可以写第二个条件

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

但不需要。

更新2

not移除where,此处not表示active

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

更新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范围,我认为您将实现目标,请记住未经测试。

希望它能够奏效。

答案 1 :(得分:1)

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

另外,对于最好的Rails实践,您应该使用问号编写其他答案中建议的用户fool-dev之类的查询。这是为了防止SQL注入,详见更详细here

修改 所以我认为你的意思是等待意味着没有任何Todo的项目或那些等待Todo(start_at > now)的项目。我认为这应该有效:

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

第一部分是选择没有Todo的项目,第二部分是自我解释。