2011-05-27 43 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