Rails associations: How do I limit/scope a has_many :through with multiple self-referencing conditions?

偶尔善良 提交于 2019-12-06 16:09:18

问题


What's the best way to do this? I'm trying something like this, but it feels... wrong. (NOTE: It's all about the :conditions in the has_many association...)

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

What I'm trying to do

I need to pass multiple conditions on a has_many :through association and refer to the "self" model to do comparisons in those conditions.

I've found examples with multiple conditions. I've found examples with self-referencing comparisons. But I can't find anything with both of those elements. This makes me think I'm doing it wrong.

Background and definitions

A Submission records a snapshot of a Checklist and its associated Jobs at a point in time. So, I want to be able to say "submission.jobs" and see the Jobs that were associated with the Submission's Checklist at the time the Submission itself was created.*

*It's actually slightly more complicated: I want the Jobs that existed when the Submission was created AND that were not yet archived at that time.

The Checklist is dynamic and can change over time, but I always keep historical records intact via a home-grown archiving system, so the Jobs on a Checklist when a Submission was created for that Checklist would be the Checklist's Jobs where Job.created_at was before Submission.created_at (and not yet archived).

So, although a Submission belongs_to a Checklist, and the Checklist has_many Jobs, the only Jobs that ever matter for a particular Submission are the Jobs that existed (and were not yet archived) at the time the Submission was created.


回答1:


You can use a scope on Job and perhaps a method added to 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


来源:https://stackoverflow.com/questions/16203576/rails-associations-how-do-i-limit-scope-a-has-many-through-with-multiple-self

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!