我有以下型号
class User < ActiveRecord::Base
has_many :occupations, :dependent => :destroy
has_many :submitted_jobs, :class_name => 'Job', :foreign_key => 'customer_id'
has_many :assigned_jobs, :class_name => 'Job', :foreign_key => 'employee_id'
end
class Job < ActiveRecord::Base
belongs_to :customer, :class_name => 'User', :foreign_key => 'customer_id'
belongs_to :employee, :class_name => 'User', :foreign_key => 'employee_id'
belongs_to :field
end
class Occupation < ActiveRecord::Base
belongs_to :user
belongs_to :field
belongs_to :expertise
end
以及Field
(只是名称和ID)和Expertise
(名称和整数排名)。
我需要创建一个类似于以下伪代码的过滤器
select * from jobs where employee_id == current_user_id
or employee_id == 0
and current_user has occupation where occupation.field == job.field
and if job.customer has occupation where occupation.field == job.field
current_user.occupations must include an occupation where field == job.field
and expertise.rank > job.customer.occupation.expertise.rank
你可以通过这个复杂的查询看到我如何快速耗尽我的SQL知识。
你会怎么做?正确的SQL会很棒,但如果一个Rails人员可以指出我使用ActiveRecord方法的正确方法,那也很棒。或许我不是很好地构建我的模型;我愿意接受各种建议。
谢谢!
答案 0 :(得分:2)
我可能错过了一些内容,并没有考虑重构模型,但是可能有助于您获得完整解决方案或如何重新构建查询的内容
未对代码进行测试或语法检查
@jobs = Job.
joins(:employee,:occupation).
includes(:customer => {:occupations => :expertise}).
where(:employee_id => current_user.id).
where("occupations.field_id = jobs.field_id").all
user_occupations = current_user.occupations.include(:expertise)
user_occupations_by_field_id = user_occupations.inject({}) do |hash,oc|
hash[oc.field_id] = oc
hash
end
@jobs.reject! do |j|
common_occupations = j.customer.occupations.select do |oc|
if c = user_occupations_by_field_id[oc.field_id]
!user_occupations.select do |eoc|
c.field_id == eoc.field_id && c.expertise.rank > oc.expertise.rank
end.empty?
else
true
end
end
end