【问题标题】:Rails associations: How do I limit/scope a has_many :through with multiple self-referencing conditions?Rails 关联:如何通过多个自引用条件限制/限定 has_many :through?
【发布时间】:2013-04-18 16:30:45
【问题描述】:

最好的方法是什么?我正在尝试这样的事情,但感觉......错了。 (注意:这都是关于 has_many 关联中的 :conditions...)

class Submission < ActiveRecord::Base
  belongs_to :checklist
  has_many :jobs, :through => :checklist, :source => :job, :conditions => ["jobs.archived = false OR jobs.archived_at > #{self.created_at} OR jobs.created_at < #{self.created_at}"]
end

Rails 3.2.11、Ruby 1.9.3

我要做什么

我需要在 has_many 上传递多个条件:通过关联引用“自我”模型在这些条件下进行比较。

我找到了具有多种条件的示例。我找到了自我引用比较的例子。但是我找不到这两个元素的任何东西。这让我觉得我做错了。

背景和定义

提交记录了检查表及其相关作业在某个时间点的快照。因此,我希望能够说“submission.jobs”并查看在创建提交本身时与提交的清单相关联的作业。*

*实际上稍微复杂一些:我想要创建提交时存在且当时尚未存档的作业。

清单是动态的并且会随着时间而改变,但我总是通过一个本土的存档系统保持历史记录的完整性,因此当为该清单创建提交时,清单上的作业将是清单中的 Jobs where Job. created_at 在 Submission.created_at 之前(尚未归档)。

因此,虽然一个提交属于_一个清单,并且清单有_许多作业,但对于特定提交而言唯一重要的作业是在创建提交时存在(并且尚未归档)的作业。

【问题讨论】:

    标签: ruby-on-rails associations conditional-statements has-many-through


    【解决方案1】:

    您可以在Job 上使用范围,也可以使用添加到Submission 的方法:

    class Job < ActiveRecord::Base
      scope :unfinished_since, lambda { |timestamp| 
        where("archived = ? OR archived_at > ? OR created_at < ?", false, timestamp, timestamp)        
      }
    end
    
    class Submission < ActiveRecord::Base
      belongs_to :checklist
      has_many :jobs, :through => :checklist, :source => :job
    
      def unfinished_jobs
        jobs.unfinished_since(self.created_at)
      end
    end
    

    【讨论】:

    • 优秀的答案。 FWIW,我不得不稍微调整标准,所以看起来像这样:where("created_at &lt; ? AND (archived = ? OR archived_at &gt; ?)", timestamp, false, timestamp)。我提供的标准基本上是拉提交之前创建的任何工作;我实际上是想使用标准来提取在提交之前创建的任何作业,但在提交之前没有存档。但是鉴于我最初提供的标准,您的回答是正确的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多