我有一个任务管理应用程序,用户可以在其中创建“等待”任务。如果尚未收到他们正在等待的项目,则该任务仍处于活动状态。
我正在尝试将“可操作”范围设置为包含以下任务:
没有等待
class Task < ActiveRecord::Base
has_many :waiting_fors
def self.actionable
where("snooze_date <= ? OR snooze_date IS ?", Time.now, nil ).where(complete: false)
.includes(:waiting_fors).where("waiting_fors.received_date IS NOT ?", nil)
end
class WaitingFor < ActiveRecord::Base
belongs_to :task
end
然而,它只是过滤到只显示一个项目有一个waiting_for并且waiting_for有一个received_date。
对于我出错的地方有任何建议吗?
更新:
这就是我现在所拥有的。如果任务要么没有等待,要么有一个等待接收,那么它就能正常工作。
scope :not_snoozed, -> {where("snooze_date <= ? OR snooze_date IS ?", Time.now, nil)}
scope :incomplete, -> {where(complete: false)}
scope :no_waiting_fors, -> {includes(:waiting_fors).where(waiting_fors: {id: nil})}
scope :not_received, -> {includes(:waiting_fors).where.not(waiting_fors: {received_date: nil})}
scope :actionable, -> {incomplete.not_snoozed.where(id: (Task.no_waiting_fors+Task.not_received).map(&:id))}
但是,如果一个任务有两个waiting_fors并且只有一个有一个收到的日期(这意味着我们还在等待一些东西),它就会显示为活动状态。
答案 0 :(得分:0)
你的意思是
where("waiting_fors.received_date = ?", nil)
而不是
where("waiting_fors.received_date IS NOT ?", nil)
答案 1 :(得分:0)
所有这些都可以通过命名范围轻松完成。您可以构建不同条件的范围,然后在要使用多个条件时组合范围。你在使用Rails 4吗?这将是语法:
class Task < ActiveRecord::Base
has_many :waiting_fors
scope :no_waiting_fors, -> {includes(:waiting_fors).where(waiting_fors: {id: nil})}
scope :not_received, -> {includes(:waiting_fors).where.not(waiting_fors: {received_date: nil})}
scope :actionable, -> {where(id: (Task.no_waiting_fors+Task.not_received).map(&:id))}
end
像这样,您可以获得灵活且可扩展的配置。
答案 2 :(得分:0)
尝试使用SQL的NOT IN功能将范围更新为:
scope :received, -> {includes(:waiting_fors).where("tasks.id not in (select tasks.id from tasks inner join waiting_fors on waiting_fors.task_id = tasks.id where waiting_fors.received_date is null)")}
scope :actionable, -> {incomplete.not_snoozed.where(id: (Task.no_waiting_fors+Task.received).map(&:id))}