2012-01-21 64 views
0

我有一個公認的醜陋的查詢來做,找到與當前角色相關的特定角色。這條線產生正確的結果:如何將德米特法律應用於此?

@person_event_role.event_role.event.event_roles. 
    joins(:mission_role).where(:mission_roles => {:title => 'Boss'}). 
    first.person_event_roles.first.person 

(您可以從多個這些調用的推斷協會)

得到這個信息的唯一途徑,需要一噸的數據庫結構的知識,但要刪除耦合...這將需要填補在該鏈的每一步幫助功能,以回饋所需的信息...

回答

1

我認爲這裏要做的事情是創建幫助函數在適當情況下。我不清楚你的關聯鏈的起點在哪裏,但我可能會爲它分配一個方法#event,返回event_role.event。從那裏,一個event#boss_role,或任何有意義的語義,並且該方法是

event_roles.joins(:mission_role).where(:mission_roles => {:title => 'Boss'}).first 

最後,還對Event模型,有一個#boss方法,後者

boss_roles.first.person_event_roles.first.person 

所以,您的原始查詢變爲

@person_event_role.event.boss 

鏈條的每條腿都是自包含的,並且易於下劃Tand,而且它不需要你的連鎖店的開始就無所不知。我並不完全理解這些關聯的全面影響,但我敢肯定,將其分解爲三種或四種模型方法會給您提供清晰的閱讀和您正在尋找的關注點的分離。你甚至可以進一步分解,以便更容易閱讀,但這成爲一種風格問題。

希望有幫助!

以下是原來的提問

我想我遵循了這一建議,並結束了:

@person_event_role.get_related_event_roles_for('Boss').first.filled_by.first 

#person_event_role: 
def get_related_event_roles_for(role) 
    event.event_roles_for(role) 
end 

def event 
event_role.event 
end 

#event: 
def event_roles_for(role) 
    event_roles.for_role(role) 
end 

#event_role: 
scope :for_role, lambda {|role| joins(:mission_role).where(:mission_roles => {:title => role})} 
def filled_by 
    person_event_roles.collect {|per| per.person} 
end 
+0

這樣的作品,但它只是許多相互作用的一個......的模型將要充滿這些噸...... – DGM