我认为这里要做的是在适当的地方创建辅助函数。我不清楚您的关联链的开头是什么,但我可能会为其分配一个#event
返回的方法event_role.event
。从那里开始, anevent
有一个#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
然后,链条的每条腿都是独立的且易于理解,并且不需要您的链条的开头对它的结尾无所不知。我不完全理解这些关联的全部范围,但我很确定只需将其分解为三个或四个模型方法,就可以让您清楚地阅读和分离您正在寻找的关注点。你甚至可以进一步分解它以增加阅读的便利性,但这变成了风格问题。
希望有帮助!
以下由提问者原创
我想我遵循了这个建议并最终得到:
@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