ActiveRecord 通过两个关联加入
ActiveRecord join through two associations
鉴于存在两种可能的关联,我如何获得包含特定 User
的所有唯一 Jobs
的 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
当然这是未经测试的代码,但这应该能让您入门?
鉴于存在两种可能的关联,我如何获得包含特定 User
的所有唯一 Jobs
的 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
当然这是未经测试的代码,但这应该能让您入门?