Не найдены вспомогательные методы для монтирования Rails при маршрутизации из основного приложения

У меня есть модуль в виде монтируемого двигателя, установленного в главном приложении через

mount MyEngine::Engine, :at => '/myengine'

У меня все пространство имен находится в negine, и у движка есть свои представления в engine/app/views/myengine/

Все работает нормально, когда я запускаю сервер rails, затем пытаюсь получить доступ

локальный:3000/myengine

затем перейдите в корень основного приложения и вернитесь к движку по ссылке в индексном представлении основного приложения.

Однако, когда я запускаю сервер, перехожу к localhost:3000 и оттуда кликаю по ссылке на модуль движка, он пытается правильно получить представления, однако методы, содержащиеся в помощниках движка, выдают ошибку при вызове, так как они не определены.

Я на рельсах 4

2 ответа

Решение

Я использовал eager_load, чтобы загрузить монтируемый движок в его инициализированном в основном приложении приложении, и теперь все работает.

Myengine::Engine.eager_load!

Я тоже столкнулся с этой проблемой. Я определил ApplicationController внутри моего двигателя и видел NoMethodErrorкогда я пытался использовать вспомогательные методы внутри одного из контроллеров моего двигателя.

Эта проблема

Код выглядел примерно так:

в my_engine/app/controllers/my_engine/application_controller.rb

module MyEngine
  class ApplicationController < ActionController::Base
    helper ApplicationHelper
  end
end

в my_engine/app/controllers/my_engine/projects_controller.rb

module MyEngine
  class ProjectsController < ApplicationController
    def new
      # some action code here
    end
  end
end

в my_engine/app/helpers/my_engine/application_helper.rb

module MyEngine
  module ApplicationHelper
    def translations_include_tag
      javascript_include_tag "translations-#{I18n.locale}.js"
    end
  end
end

Если бы я перешел к маршруту в приложении host rails, а затем щелкнул ссылку, которая перешла на my_engine / projects / new, я бы получил NoMethodError поговорка translations_include_tag не существовало

Объяснение

Я думаю, что это произошло, потому что у приложения было два класса с одинаковым именем: ApplicationController в MyEngine а также ApplicationController в приложении хоста. Когда первый маршрут за пределами двигателя посещается, Rails автоматически загружает ApplicationController из хост-приложения. Это означает, что Rails ассоциирует главное приложение ApplicationController с именем "ApplicationController". Когда вы переходите к my_engine/projects/new, Rails загружается лениво ProjectsController который также наследует от ApplicationController, Rails / ruby ​​думает, что вы имеете в виду то же самое ApplicationController он уже загружен, так что в действительности ProjectsController заканчивается наследование от хост-приложения ApplicationController вместо того, что в двигателе. Так как translations_include_tag метод не определен в приложении хоста ApplicationControllerРубин поднимает NoMethodError когда представление пытается вызвать это.

Решение

Я смог решить проблему, явно унаследовав от MyEngine"s ApplicationController:

в my_engine/app/controllers/my_engine/projects_controller.rb

module MyEngine
  # changed from just plain 'ol ApplicationController
  class ProjectsController < ::MyEngine::ApplicationController
    def new
      # some action code here
    end
  end
end

После исправления проблемы наследования NoMethodError ушел.

В принятом ответе говорится, что нужно использовать энергичную загрузку, что также решит проблему, потому что это заставляет двигатель ApplicationController загрузить первым. Так как двигатель ApplicationController внутри пространства имен MyEngineЭто полное имя MyEngine::ApplicationController, которое не конфликтует с основным приложением. ApplicationController потому что имена констант разные.

Вы должны явно включить помощников в свой lib/engine.rb файл:

initializer 'your-gem-name.setup_helpers' do |app|
    app.config.to_prepare do
      ActionController::Base.send :include, HelperModuleName
    end
  end
end
Другие вопросы по тегам