我如何应用得墨忒耳法?
我有一个公认的丑陋的查询,要找到与当前角色相关的特定角色。 该行产生正确的结果:
@person_event_role.event_role.event.event_roles. joins(:mission_role).where(:mission_roles => {:title => 'Boss'}). first.person_event_roles.first.person
(您可以从多个调用中推断出关联)
获取此信息的唯一方法需要大量数据库结构的知识,但要删除耦合…这需要在该链的每个步骤中填充一堆辅助函数以返回所需的信息。 ..
我认为这里要做的是在适当的时候创建辅助函数。 我不清楚你的关联链的开头是什么,但我可能#event
它分配一个返回event_role.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