Rails 3.1: лучший способ показать помощник движка в клиентском приложении - PullRequest
25 голосов
/ 10 января 2012

Я нашел несколько статей, посвященных проблеме помощников в движке, которые недоступны для потребляющего (родительского) приложения.Чтобы убедиться, что мы все на одной странице, допустим, у нас есть это:

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 к родителюприложение-помощник приложения.Тем не менее, это не работает.Кто-нибудь может помочь мне понять, почему это более лучшее решение не работает?

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

Ответы [ 5 ]

44 голосов
/ 10 марта 2012

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

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
6 голосов
/ 31 июля 2013

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

module MyEngine
  class Engine < Rails::Engine
    isolate_namespace MyEngine

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

  end
end
6 голосов
/ 01 октября 2012

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

Обновление: Тем временем три статьи, и еще есть некоторая информация. Пожалуйста, дайте мне отзыв.

1 голос
/ 22 октября 2014

Включить этот код в 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
1 голос
/ 23 февраля 2012
module YourEngine
  module Helpers
    def a_helper
    end

    ...
  end
end

ActionController::Base.send(:helper, YourEngine::Helpers)
...