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's 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 в помощник приложения родительского приложения. Однако это не работает. Может ли кто-нибудь помочь мне понять, почему это лучшее решение не работает?

Я использую рубин 1.8.7 с рельсами 3.1.3. Дайте мне знать, если я пропустил какую-либо важную информацию, относящуюся к проблеме, и заранее спасибо.


person ynkr    schedule 10.01.2012    source источник


Ответы (4)


Вы можете создать инициализатор для этого следующим образом:

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
person JDutil    schedule 09.03.2012
comment
На самом деле вы можете упростить еще больше: helper MyEngine::ImportantHelper без отправки. Я обновил свой пост. - person JDutil; 06.04.2012
comment
Это изменилось? Кажется, что все мои помощники загружаются автоматически без кода выше! Вот мой движок: github.com/sientia-jmu/iq_menu - person Joshua Muheim; 20.09.2012
comment
Действительно кажется, что все помощники автоматически включаются в каждый контроллер, по крайней мере, при наличии движка --full. - person Joshua Muheim; 27.09.2012
comment
Возможно, это изменилось с тех пор, как я впервые опубликовал это, но в то время это было необходимо. - person JDutil; 28.09.2012
comment
Мы попробовали решение в нашем движке rails 3.2.8 и получили ошибку: ActionView::Helpers::ControllerHelper#session делегирован на controller.session, но контроллер равен нулю: #‹ActionView::Base:0x3e14a10 @_config={}, @view_renderer=#‹ActionView::Renderer:0x3dfe1c8 @lookup_context=#‹ActionView::LookupContext:0x3dfe2d0 @details_key=nil, @details={:locale=›[:en]... - person user938363; 28.11.2012
comment
Он изменился. В последних версиях Rails все помощники загружаются автоматически. api.rubyonrails.org/classes/Rails/Engine.html - person danielpcox; 25.01.2013
comment
здесь с рельсами 4 даже помощники двигателя не работали внутри двигателя. Использование приведенного выше кода помогло :) - person Marcus Mansur; 20.08.2013
comment
Я думаю, что они не загружаются, если движок изолирован, удаление isolate_namespace MyEngine означает, что они загружаются, но, конечно, имеют другие побочные эффекты. - person Kris; 04.09.2013
comment
да, чувак, у меня это сработало в rails 4 с монтируемым движком. - person jspooner; 18.09.2013
comment
Работал на рельсах5. - person Waclock; 16.12.2016

Я написал две записи в блоге о создании движков с нуля, и после них все должно работать как положено (без необходимости дополнительных настроек). Возможно, вас еще интересует:

Обновление. На данный момент это три статьи, и еще будет немного информации. Пожалуйста, дайте мне обратную связь.

person Joshua Muheim    schedule 01.10.2012
comment
Ссылка умерла :/ - person Waclock; 19.12.2016

Если вы хотите сохранить код в движке, а не в каждом реализующем приложении, используйте это:

module MyEngine
  class Engine < Rails::Engine
    isolate_namespace MyEngine

    config.to_prepare do
      MyEngine::ApplicationController.helper Rails.application.helpers
    end

  end
end
person Brad Werth    schedule 31.07.2013

Включите этот код в 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
person rplaurindo    schedule 21.10.2014