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

Использование 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, а не миксин, который я поставил в качестве инициализатора. Поэтому, как только я изменил код, я потерял все свои расширенные функции.

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


person philt5252    schedule 19.03.2012    source источник


Ответы (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
person holtkampw    schedule 19.03.2012