Как расширить модель монтируемого двигателя внутри другого монтируемого двигателя с перезагрузкой среды разработки

Использование Rails 3.2.2 и Ruby 1.9.2.

У меня есть рельсовый двигатель EngineA который объявляет User форма наследования классов ActiveRecord::Base, У меня другой двигатель EngineB который хочет внедрить функциональность в EngineA::User, Прямо сейчас то, что я сделал, показано ниже:

Способ 1:

#EngineA app/models/engine_a/user.rb
module EngineA
  class User < ActiveRecord::Base
    has_attached_file :avatar
    has_many :somethings
  end
end

#EngineB lib/engine_b/user.rb
module EngineB
  module User
    def self.extended obj
      obj.class_eval do
        has_many :something_elses
      end
    end
  end
end

EngineA::User.extend EngineB::User

Это дает мне uninitialized constant EngineA::User ошибка. Даже когда мне требуется этот конкретный файл, я сталкиваюсь с проблемой EngineA нужна скрепка, чтобы has_attached_file понятно. Эта дорога закончилась, когда я понял, что мне нужно знать и требовать зависимости для EngineA внутри EngineB,

Способ 2:

Я использовал тот же код, что и раньше, за исключением того, что я удалил последнюю строку EngineA::User.extend EngineB::User от EngineB файл user.rb. Затем я переместил этот вызов в инициализатор внутри EngineB,

#EngineB config/initializers/my_mixin.rb
EngineA::User.extend EngineB::User

Это сработало отлично!!! За исключением режима разработки, когда я изменял код и модели обновлялись. Единственное, что было обновлено, было EngineA::User а не тот миксин, который я поставил как инициализатор. Поэтому, как только я изменил код, я потерял всю свою расширенную функциональность.

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

1 ответ

Решение

Согласно документации по конфигурации, вы можете использовать ActionDispatch обратный вызов для загрузки предметов. Эти обратные вызовы будут выполняться при каждом запросе, если cache_classes установлено в false, как в режиме разработки.

Внутри вашего EngineB.rb файл, вы можете попробовать что-то вроде этого:

if Rails.env.development?
    ActionDispatch::Callbacks.to_prepare do
        load "#{File.expand_path(File.dirname(__FILE__))}/../config/initializers/my_mixin.rb"
    end
end
Другие вопросы по тегам