Модель с использованием модулей в Rails-приложении
У меня есть модель, которая требует загрузки внешних данных из вспомогательного источника. Существует несколько веб-сервисов, в которых моя модель может извлекать данные из (swappable), но я не хочу создавать код, который затруднит изменение сервисов (затраты существенно различаются в зависимости от переменной и фиксированного использования и, скорее всего, изменяются потребуется).
Я хотел бы создать драйвер для взаимодействия (а затем создать дополнительные пользовательские драйверы, если служба требует переключения). К сожалению, из-за жесткой связи драйвера и модели нет смысла извлекать код в плагин или драгоценный камень. Я извлек весь код в модуль (см. Пример) и в настоящее время имеет код, указанный выше моей модели.
module Synchronize
def refresh
self.attributes = ...
self.save
end
end
class Data < ActiveRecord::Base
include Synchronize
end
Есть ли в Rails (3.0.0) соглашение для хранения модулей, тесно связанных с моделями? Должен ли я использовать плагин для этого? Связано ли это с каталогом "app/helpers"? Если нет, то где наиболее подходящее место для хранения кода? Спасибо!
Ответы
Ответ 1
Вы правы, если модуль плотно связан с этой конкретной моделью, то он не является хорошим кандидатом для gem/plugin.
app/helpers/предназначен для просмотра вспомогательных методов и не должен содержать модули, которые предназначены исключительно для смешивания с моделями.
Одно место, в которое вы могли бы поместить модуль, находится внутри lib/. Это для кода, который действительно не подходит нигде в приложении/и часто является исходным домом слабо связанного кода, прежде чем он будет перемещен в плагин (но это не сложно и быстро). Однако, поскольку ваш модуль тесно связан с вашей моделью, lib/может быть не лучшим местом для него.
Я знаю, что 37signals (и другие) используют концепцию "проблем" как способ сохранения связанного кода модели, организованного в модулях. Это осуществляется путем создания приложений/проблем/и размещения модулей там. Затем этот каталог добавляется в путь загрузки приложения в config/application.rb(config/environment.rb для Rails 2) с помощью:
config.load_paths += %W(#{Rails.root}/app/concerns)
Затем модуль можно смешать с моделью как обычно.
Здесь оригинальное сообщение в блоге об этом Jamis Buck - http://weblog.jamisbuck.org/2007/1/17/concerns-in-activerecord
Другой вариант, который я лично предпочитаю, хотя он и не включает модули, использует этот плагин:
http://github.com/jakehow/concerned_with
Надеюсь, что это поможет.
Ответ 2
Эта ссылка помогла мне обойти это.
http://ander.heroku.com/2010/12/14/concerns-in-rails-3/
Я вставлял его в каталог model/extensions. Справочник проблем имеет смысл, но слово "проблемы" не кажется мне очевидным. Возможно, он будет расти на мне.
Я также добавил путь расширения в application.rb
config.autoload_paths += %W(#{config.root}/app/models/extensions)