我有一个公认的难看的查询,要找到与当前角色相关的特定角色。该行产生正确的结果:
@person_event_role.event_role.event.event_roles.
joins(:mission_role).where(:mission_roles => {:title => 'Boss'}).
first.person_event_roles.first.person
(您可以推断多个呼叫中的关联)
获取此信息的唯一方法需要大量数据库结构的知识,但要删除耦合...这需要在该链的每个步骤中填充一堆辅助函数以返回需要的信息...
答案 0 :(得分: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
链条的每一条腿都是独立且易于理解的,并且它不需要链条的开头就其结尾而言是无所不知的。我并不完全理解这些关联的完整范围,但我很确定只要将其分解为三种或四种模型方法,就能让您清楚地阅读和分离您正在寻找的关注点。你甚至可以进一步分解它以便于阅读,但这会成为一种风格问题。
希望有所帮助!
以下是原始提问者
我想我遵循了这个建议并最终得到了:
@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