鉴于存在两种可能的关联,如何获得具有特定Jobs
的所有唯一User
的ActiveRecord集合?
class User
has_many :assignments
has_many :jobs, through: assignments
has_many :events
has_many :jobs_via_events, through: :events, source: :jobs
end
class Assignment
belongs_to :user
belongs_to :job
end
class Event
belongs_to :user
belongs_to :job
end
class Job
has_many :assignments
has_many :events
end
到目前为止,我所能想到的最好的方法是使用多个联接,但是并没有得到正确的结果:
Job.joins("INNER JOIN assignments a ON jobs.id = a.job_id").joins("INNER JOIN events e ON jobs.id = e.job_id").where("a.user_id = ? OR e.user_id = ?", userid, userid)
有什么建议吗?
一种简单的方法是先收集所有作业ID,然后获取这些ID的所有作业。
我们首先要求用户提供所有工作ID的数组:
event_job_ids = Event.where(user_id: user).select(:job_id).map(&:job_id)
assignment_job_ids = Assignment.where(user_id: user).select(:job_id).map(&:job_id)
all_job_ids = (event_job_ids + assignment_job_ids).uniq
请注意,根据您使用的rails版本,最好将select(:job_id).map(&:job_id)
替换为.pluck(:job_id)
(这应该更有效,但是select.map
然后获得组装ID的作业非常简单:
jobs = Job.where(id: all_job_ids)
这是一种幼稚的方法,我们如何批准呢?如果我要写查询,我会写类似下面的内容
select * from jobs
where id in (
select job_id from assignments where user_id=#{user_id}
union
select job_id from events where user_id=#{user_id}
)
那么我们如何将其转换为范围?
class User
def all_jobs
sql = <<-SQL
select * from jobs
where id in (
select job_id from assignments where user_id=#{self.id}
union
select job_id from events where user_id=#{self.id}
)
SQL
Job.find_by_sql(sql)
end
当然,这是未经测试的代码,但这应该可以帮助您入门吗?