Подтвердить что ты не робот

Доступ к основным помощникам приложения при перегрузке Rails Engine View/Layout

Я создал простой Rails Engine, чтобы предоставить некоторую общую функциональность (фотогалерею) для приложения. Я хочу иметь возможность переопределить стандартную частицу _header, чтобы меню галереи соответствовало моему главному приложению. В моем заголовке я вызываю помощника, который является частью application_helpers (основного приложения), но я продолжаю получать ошибки "undefined". Из того, что я могу сказать, основное приложение application_helpers не включается (очевидно), когда я переопределяю макет приложения для двигателей или его частичные.

Итак, мой вопрос: как переопределить представление ядра в главном приложении и получить доступ к основным вспомогательным методам приложения? Мне все равно нужен доступ к помощникам двигателя, а также не для того, чтобы испортить функциональность двигателя.

Нужно ли также переопределять контроллеры? кажется, очень много, чтобы получить помощников.

Спасибо

Rails 3.1.3

4b9b3361

Ответ 1

Посмотрите это сообщение в блоге: http://www.candland.net/2012/04/17/rails-routes-used-in-an-isolated-engine/ Автор добавляет определение method_missing к помощнику приложения для доступа к помощникам родительских приложений.

/config/initializers/blogit.rb

module Blogit
    module ApplicationHelper
      def method_missing method, *args, &block
        puts "LOOKING FOR ROUTES #{method}"
        if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')
          if main_app.respond_to?(method)
            main_app.send(method, *args)
          else
            super
          end
        else
          super
        end
      end

      def respond_to?(method)
        if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')
          if main_app.respond_to?(method)
            true
          else
            super
          end
        else
          super
        end
      end
    end
  end

Ответ 2

Попробуйте включить основные вспомогательные методы приложения. Например:

class MyEngineClass
  include ApplicationHelper

  #...
end

Возможно, вам придется сначала потребовать файл, хотя я бы ожидал, что Rails правильно найдет его в этом случае.

После того, как ApplicationHelper включен, вы должны иметь возможность напрямую использовать эти помощники в контроллере.

Похоже, вы можете вызвать ClassName.helper("application") для большого количества классов Rails - не уверены, что это будет работать здесь.

Ответ 3

попробуйте создать помощника в вашем приложении с тем же именем помощника в вашем движке, чтобы переопределить методы поддержки хелпера.

Я нашел эту дискуссию, особенно проницательную. Есть также некоторые интересные идеи в Документах API Rails Engine в разделе Изолированные помощники двигателя.

Ответ 4

Двигатели должны быть независимы от основного приложения, поэтому вы не можете получить доступ к своим помощникам из Engine.

Однако есть хакерские способы предоставить вашему движку доступ к помощникам основного приложения. Вот как я это сделал:

# In the main app
# initializers/share_helpers_path_with_engine.rb
PhotoGallery::Engine.class_eval do
  paths["app/helpers"] << File.join(File.dirname(__FILE__), '../..', 'app/helpers')
end

Вам нужно, конечно, изменить PhotoGallery на фактическое имя вашего класса двигателя.

Не стесняйтесь взглянуть на документацию по двигателям (раздел о путях): http://edgeapi.rubyonrails.org/classes/Rails/Engine.html

Ответ 5

Отказ от ответственности: я использовал это решение только в Rails 3.2.

Если в вашем движке у вас есть стандартный заголовок vendor/gems/my_gallery_engine/app/views/application/_header.html.erb.

Затем переопределите его в главном приложении, создав индивидуальное частичное приложение /views/application/ _header.html.erb.

Функция переопределения работает, потому что путь поиска шаблона просмотра Rails (по умолчанию) начинается с основного каталога приложений app/views, а затем выполняется поиск по приложениям/представлениям движков > в порядке загрузки.

Все ваши основные помощники приложения будут доступны в частичном.