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

Рекомендации по размещению классов в Rails-приложениях, которые не подходят нигде

Мне интересно, есть ли какие-либо рекомендации по размещению нестандартных файлов Ruby в Rails-приложениях, которые не соответствуют ни одному из каталогов по умолчанию (controllers/models и т.д.).

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

Несколько случайных примеров:

  • "стратегии", которые обрабатывают аутентификацию с помощью пароля, через facebook и т.д.
  • Объекты "XParams", которые инкапсулируют параметры или объекты "XCreator", которые обрабатывают обработку параметров для выполнения некоторого сложного действия, что в итоге приводит к созданию некоторых моделей AR в конце
  • которые обращаются к внешним API-интерфейсам или инкапсулируют эти запросы и ответы
  • поддельные модели, которые могут быть заменены реальной моделью AR (например, гостевой пользователь)
  • Задачи Resque
  • классы, которые хранят и читают информацию из Redis
  • которые выполняют некоторые конкретные действия, такие как обработка данных, генерация отчетов и т.д. и вызываются из задач Resque или задач грабли.

Теперь у меня их довольно много, некоторые из них добавлены в lib, который заканчивается как куча случайных классов и модулей, некоторые пробираются в app/models. Я хотел бы как-то это организовать, но я не знаю, с чего начать.

Должны ли только модели AR входить в app/models? Или это нормально, чтобы добавить туда какие-либо доменные или вспомогательные модели? Как вы решаете, является ли что-то моделью?

Если все, что не вписывается в app, перейдите в lib? Или, может быть, я должен добавить несколько новых настраиваемых подкаталогов в app? Какие подкаталоги и как разделить пользовательские классы?

Как вы справляетесь с этим в своих проектах? Я знаю, что каждый проект немного отличается, но должно быть некоторое сходство.

4b9b3361

Ответ 1

Хороший вопрос - у меня нет конкретного ответа для вас

но я рекомендую проверить этот пост - http://blog.codeclimate.com/blog/2012/02/07/what-code-goes-in-the-lib-directory/ - обязательно прочитайте все комментарии

в текущем проекте у меня есть тонна объектов не-ActiveRecord в приложении/моделях, она работает, но не идеальна я добавляю "повторно используемый" неспецифический код в lib

другие альтернативы, которые я пробовал на сторонних проектах (скажем, у нас есть куча объектов команд) rails - это боль, когда дело касается пространств имен под приложением, по умолчанию загружает все в одно и то же пространство имен

app/
  commands/
    products/create_command.rb         # Products::CreateCommand
    products/update_price_command.rb   # Products::UpdatePriceCommand

alternate, все, кроме рельсов под src или каталога app_name

app/
  src/
    commands/
      create_product.rb         # Commands::CreateProduct
      update_product_price.rb   # Commands::UpdateProductPrice

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

Ответ 2

Вы затрагиваете несколько различных вариантов использования, и я думаю, что эта часть ближе всего к "правильному" ответу:

Теперь у меня их довольно много, некоторые из них добавлены в lib, который заканчивается кучей случайных классов и модулей, некоторые из них подкрадываются к приложениям/моделям. Я хотел бы как-то это организовать, но я не знаю, с чего начать.

Это очень хорошо в моей книге. Единственное, о чем вы не говорите, это извлечение различных предметов в отдельные драгоценные камни. Классы, которые общаются с внешними службами, являются отличными кандидатами на извлечение, а также стратегическими классами, если они достаточно общие. Они могут быть частными, поскольку запуск собственного сервера gem не является сложным, и вы можете, очевидно, повторно использовать их в приложениях ROR.

Последнее и самое конкретное, resque jobs, которое я загружаю в lib/jobs.

Мое эмпирическое правило - это какая-то модель, она переходит в app/models. Если нет, то он, вероятно, принадлежит lib или некоторому соответствующему названному подкаталогу, например. lib/jobs, lib/extensions, lib/external или тому подобное.

Ответ 4

Я помещаю любые классы моделей (например, подклассы STI) в apps/models. Я помещаю свои другие классы в lib, поскольку это кажется лучшим местом для их размещения. Мне легко понять, где искать. Мне также легче группировать мои тесты, так как классы модели все в одном месте.

В соответствии с Конвенцией я не могу помещать вспомогательные классы в app/models. Если они являются классами презентаторов, они принадлежат app/helpers. Если они не тогда, то lib кажется лучшим местом для них.

Ответ 5

Часто мои классы находят свой путь в lib в подкаталогах, где модули с тем же именем, что и подкаталог, отвечают за их включение. (Rails очень трогательно относится к именам файлов и именам классов, когда дело доходит до автозагрузчика.)

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