Rails 3.1: лучший способ открыть помощника для двигателя в клиентском приложении
Я нашел несколько статей, посвященных проблеме помощников в движке, недоступном для потребительского (родительского) приложения. Чтобы убедиться, что мы все на одной странице, скажем, у нас есть следующее:
module MyEngine
module ImportantHelper
def some_important_helper
...do something important...
end
end
end
Если вы посмотрите документацию rails engine в разделе "Изолированные помощники двигателя" (L293), в нем говорится:
# Sometimes you may want to isolate engine, but use helpers that are defined for it.
# If you want to share just a few specific helpers you can add them to application's
# helpers in ApplicationController:
#
# class ApplicationController < ActionController::Base
# helper MyEngine::SharedEngineHelper
# end
#
# If you want to include all of the engine helpers, you can use #helpers method on an engine's
# instance:
#
# class ApplicationController < ActionController::Base
# helper MyEngine::Engine.helpers
# end
Итак, если я попрошу кого-нибудь, кто использует мой движок, добавить это в свой application_controller.rb, тогда они получат доступ ко всем моим важным вспомогательным методам:
class ApplicationController < ActionController::Base
helper MyEngine::ImportantHelper
end
Это то, что я хочу, и это работает, но такая боль, особенно если, как и в моем случае, все, что предоставляет механизм, может/должно использоваться в любом месте приложения-потребителя. Поэтому я немного потянулся и нашел решение, в котором предлагалось сделать следующее:
module MyEngine
class Engine < Rails::Engine
isolate_namespace MyEngine
config.to_prepare do
ApplicationController.helper(ImportantHelper)
end
end
end
Теперь это именно то, что я хочу: добавить весь мой метод ImportantHelper в помощник приложения родительского приложения. Однако это не работает. Может кто-нибудь помочь мне понять, почему это более-лучшее решение не работает?
Я запускаю ruby 1.8.7 с рельсами 3.1.3. Дайте мне знать, если я пропустил какую-либо важную информацию о проблеме, и спасибо заранее.
Ответы
Ответ 1
Вы можете создать инициализатор, чтобы выполнить это следующим образом:
module MyEngine
class Engine < Rails::Engine
initializer 'my_engine.action_controller' do |app|
ActiveSupport.on_load :action_controller do
helper MyEngine::ImportantHelper
end
end
end
end
Ответ 2
Я написал два сообщения в блоге о создании движков с нуля, и после них все должно работать как ожидалось (без дополнительных конфигураций). Возможно, вас все еще интересуют:
Обновление:. В то же время это три статьи, и есть еще какая-то информация. Пожалуйста, дайте мне отзыв.
Ответ 3
Если вы хотите сохранить код в движке, а не в каждом внедряющем приложении, используйте это:
module MyEngine
class Engine < Rails::Engine
isolate_namespace MyEngine
config.to_prepare do
MyEngine::ApplicationController.helper Rails.application.helpers
end
end
end
Ответ 4
module YourEngine
module Helpers
def a_helper
end
...
end
end
ActionController::Base.send(:helper, YourEngine::Helpers)
Ответ 5
Включите этот код в engine.rb также очень полезно
config.before_initialize do
ActiveSupport.on_load :action_controller do
helper MyEngine::Engine.helpers
end
end
В основном ваш движок будет выглядеть как
module MyEngine
class Engine < Rails::Engine
isolate_namespace MyEngine
# Here comes the code quoted above
end
end