我如何应用得墨忒耳法?

我有一个公认的丑陋的查询,要找到与当前角色相关的特定角色。 该行产生正确的结果:

@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