Подтвердить что ты не робот

Как организовать модели Rails, которые слишком толстые?

Хорошая практика - перевести логику с контроллера в модель. Но в любой сложной системе это неизменно приводит к очень большому файлу, даже если большинство методов являются одним лайнером по пути Rails.

Я прибегал к разделению моделей на другие модули и включая их в исходной модели, например model_flags, model_validation и т.д. У кого-то есть лучший способ?

Изменить: я выбрал новый ответ, который предложил использовать ActiveConcern. Кроме того, для всех, кто заинтересован в организации кода, эта статья, Создание моделей ActiveRecord Thin, должна очень помочь.

4b9b3361

Ответ 1

Я понимаю, что это довольно старый вопрос, и он был отмечен как ответ, но у него все еще есть хороший сок Google, поэтому я подумал, что стоит добавить...

В Rails 3 представлен ActiveSupport:: Концерн, который может использоваться для модуляции поведения, разделяемого между моделями. Или, если на то пошло, уменьшать модели, которые стали слишком толстыми.

Сам DHH представляет собой красивый, сжатый пример:

https://gist.github.com/1014971

Ответ 2

Я бы не сделал этого по нескольким причинам.

Сначала вы нарушаете предположение, что все будет там, где они должны быть, что, вероятно, является самым большим бонусом для рельсов в первую очередь. Новый человек может идти по вашему проекту и легко перемещаться по нему, если вы вставляете модельный материал в свою модель. Если вы вытащите его, вы просто добавите задержку и некоторую путаницу, особенно если единственная логика для удаления чего-то в модуль - это уменьшить размер модели.

Во-вторых, вы почти ничего не получаете от него, и вы что-то теряете. Размер файла не имеет значения в наши дни, когда почти все редакторы и IDE облегчают боль в навигации больших файлов. Перемещение материала в модуль на самом деле снимает некоторые из этих современных возможностей и потребует от вас и ваших коллег или будущих сопровождающих перейти к нескольким файлам при работе над одной моделью.

Это говорит о том, что я подозреваю, что хардкор-рельсы лучше всего подходят для вас, так это то, что если ваша модель такая большая и сложная, то ваш дизайн испорчен, и ваша модель, вероятно, представляет собой несколько вещей, которые могут быть сделаны в отдельных моделях, а не в модулях,

Ответ 3

Хорошо, я бы не сказал, что кто-то из вас ошибается, чтобы поместить все в одну модель, но я думаю, что вполне справедливо и возможность разделить различные проблемы. Это, по крайней мере, компромисс.

И я отправляю ответ на свой вопрос, так как я нашел способ Rails сделать именно это: http://github.com/jakehow/concerned_with

Более подробную информацию можно найти здесь: http://m.onkey.org/2008/9/15/active-record-tips-and-tricks

Ответ 5

Не имея знаний о вашей объектной модели, вам немного сложно посоветовать, но я бы сказал, что если вы абсолютно уверены, что все проверки/ассоциации/обратные вызовы нуждаются в, чтобы быть в в этом месте все еще существуют способы разложения общих форм поведения. Поэтому, хотя я бы не просто переместил большой кусок кода из одного файла и в другой, где он просто снова открывает класс, я бы сказал, что использование модулей/плагинов для описания распространенных типов поведения - хорошая идея.

Например, если вы создаете фид активности Facebook-esque, и все должно генерировать "события", возможно, вам нужно переместить это поведение "Eventable" в модуль, который при включении определяет ассоциации/валидации/и т.д.. Я бы сказал, что этот подход на самом деле повысит ясность вашего кода, так как вручную указывать эти ассоциации повсюду не так выразительно, как объявлять что-то как событие, а также безопасно (вы будете дублировать логику в кучке мест, а когда логика меняется, вы знаете остальных...)

В целом, хотя, я бы сказал, взгляните на свою объектную модель. В вашем тестовом наборе, если вы заметили, что для всех ваших тестов требуется много настроек, это может быть хорошим показателем того, что в вашей объектной модели вам что-то не хватает. Опять же, некоторый пример кода будет большим.

Ответ 6

Модули звучат разумно. Я бы не извлекал вызовы методов (проверки, обратные вызовы, плагины и т.д.) В модули, хотя я бы ограничил извлечение своими собственными методами.

И, как всегда, это поможет, если вы разместите некоторый пример кода. Мне трудно представить общую стратегию очистки моделей, это зависит от характера кода.