2012-01-21 2 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

Смежные вопросы