2013-06-14 1 views
1

Итак, я рисую много графиков/аналитиков из своей базы данных, которые требуют нетривиального SQL для получения своих данных. Я сделал v1, просто написав много сырого SQL, и теперь я хотел бы преобразовать это в Arel.Создание многоразовых блоков Arel

Многие запросы имеют большие блоки повторного кода. В качестве простого примера я очень часто хочу получить данные по всем Lists для заданного Org. В Arel это:

loads_of_other_arel.where(lists_table[:org_id].eq(@org.id)) 

Я хотел бы факторизовать повторение lists_table[:org_id].eq(@org.id) к чему-то вроде:

loads_of_other_arel.filter_lists_by_org 

Это может быть сделано путем:

def filter_lists_by_org arel 
    arel.where(lists_table[:org_id].eq(@org.id)) 
end 

и затем вызывающему filter_lists_by_org(loads_of_other_arel), но это кажется очень процедурным, а не тем, что мы должны делать как хорошие программисты OO. Поэтому мне кажется, что мне нужно будет открыть некоторые из существующих классов Arel и обезьян-патч для некоторых методов. Это больше OO, но я чувствую себя излишним - должен ли я даже думать об этом, или я должен просто повторять Arel в каждом методе?

+1

Я не совсем уверен, что вы просите. Казалось бы, вы просто говорите о цепных прицелах. Если вы немного уберете свой вопрос, я могу попытаться ответить на него. Тем не менее, если то, что вы делаете, это хороший объектно-ориентированный дизайн, тогда вы, вероятно, не должны использовать Arel/ActiveRecord. Перфорирование ad-hoc логики запросов во всем приложении просто плотно соединяет все ваше приложение с вашим уровнем персистентности. Я бы рассмотрел что-то вроде шаблона хранилища. [Minimapper] (https://github.com/joakimk/minimapper) - хорошая реализация шаблона для SQL. –

+0

Хммм спасибо, я думаю, что области действительно могут быть ответом, хотя я и предполагал, что это не так. Я думаю, что я мог бы сделать кучу вещей, которые AR Query Interface не может обрабатывать разумно, но я буду уверен в этом, прежде чем идти дальше. – RobHeaton

ответ

1

Обычно я использую для этого области. Вот надуманный пример:

scope :filtered_by_org, ->(org_id) {where(lists_table[:org_id].eq(org_id))} 

loads_of_other_arel.filtered_by_org(@org.id) 

Чтение над documentation поможет управлять точки дома.

+1

Вы можете даже извлечь области в модуль и включить его в разные классы. – Stefan

+0

@stefan, хороший пункт. Именованная область может быть очень мощной. – Josh

+0

Интересно! Хотя я не думаю, что области Arel и ActiveRecord могут взаимодействовать таким образом - если вы делаете кучу Arel, тогда вы не можете вызвать именованную область на этом Arel. – RobHeaton