我有父模型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 }
答案 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的项目,第二部分是自我解释。