2011-05-27 80 views
0

我有以下型号帮助有太多复杂的ActiveRecord查询连接

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方法指向正确的方法,那也很棒。或者,也许我没有很好地构建我的模型;我愿意接受各种建议。

谢谢!

回答

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 
+0

'end.empty?'让我做了双重考虑,但它是有效的。这是我期待在Ruby中做的一个很好的例子。我仍然可以从纯粹的好奇心中探索适当的SQL,但这应该很好。谢谢! – Luke 2011-05-29 00:01:08

+0

是的,一切都是红宝石表达甚至方法的定义,请upvote如果你高兴地标记它回答 – Fonsan 2011-05-29 09:31:57