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

Использование 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 Ответ

2 голосов
/ 19 марта 2012

Согласно документации по конфигурации , вы можете использовать обратный вызов 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
...