У меня есть контроллер с действием, которое отображает представление. Представление нуждается в данных для рендеринга. Я знаю следующие способы подготовки и отправить его к виду:Чистые контроллеры: подготовка данных для просмотров
Использование переменных экземпляра
class CitiesController < ApplicationController def index @cities = Cities.order(:name).limit(10) end end
Это подход по умолчанию, который можно найти в Rails documentation, но она имеет некоторые недостатки :
- Он делает код действия жирным, который становится ответственным не только за логику контроллера, но и за подготовку данных.
- Мнения требуют доступа к этим данным через переменные экземпляра - эти @ -переменные нарушают принцип наименьшего удивления.
Использование методов хелперов
class CitiesController < ApplicationController helper_method :cities def index end def cities @cities ||= Cities.order(:name).limit(10) end end
Вот так я предпочитаю больше всего. Он сохраняет методы действий чистыми, поэтому я могу реализовать логику контроллера, не смешивая его с подготовкой данных одним способом. Кроме того, нет необходимости использовать таинственные переменные экземпляра в представлениях, делая их изолированными. Однако:
- Подготовка данных по-прежнему находится в контроллере. Он становится нечитаемым, когда существует много этих вспомогательных методов, особенно когда они относятся к различным действиям/представлениям.
- Необходимо наличие уникального имени для каждого вспомогательного метода. Скажем, у меня не может быть метода с именем
products
, который будет возвращать разные данные для разных действий (конечно, я могу сделать это одним способом, но это выглядело бы уродливо).
Использование шаблона фасада
Частично проблема решается в этой статье: https://medium.com/p/d65b86cdb5b1 Но я не нравится этот подход, поскольку он вводит
@magic_facade_object
в представлениях.Использование унаследованных ресурсов
Это может выглядеть красиво в примерах, но на мой взгляд, когда дело доходит до реального кода, код контроллера становится спагетти-монстра очень быстро. Другое дело, что для просмотра страниц обычно требуется не только ресурс, но и другие данные для рендеринга (блоки боковых панелей и т. Д.), И мне все еще нужно использовать другой способ его подготовки. Объединение различных подходов делает код еще более нечитаемым. Наконец, я не люблю использовать переменную
resource
, потому что не совсем понятно, что такое представление.
Итак, вот в чем вопрос. Как вы держите свои контроллеры в чистоте?