Названные маршруты в навесных рельсах двигателя

Я делаю небольшой рельсовый двигатель, который я монтирую так:

mount BasicApp::Engine => "/app"

Используя этот ответ, я убедился, что все маршруты в двигателе соответствуют следующим:

Однако - когда я (внутри двигателя) связываюсь с именованным маршрутом (определенным внутри двигателя), я получаю эту ошибку

undefined local variable or method `new_post_path' for #<#<Class:0x000000065e0c08>:0x000000065d71d0>

Запуск "rake route" ясно подтверждает, что "new_post" должен быть именованным путем, поэтому я понятия не имею, почему Rails (3.1.0) не может понять это. Любая помощь приветствуется

мой config/route.rb (для движка) выглядит так

BasicApp::Engine.routes.draw do
  resources :posts, :path => '' do
                resources :post_comments
                resources :post_images
        end
end

Я должен добавить, что это и изолированный двигатель. Однако пути вроде main_app.root_path работают нормально, а root_path - нет.

4 ответа

Правильный путь

Я считаю, что лучшее решение - позвонить new_post_path на прокси маршрутов Engine, который доступен в качестве вспомогательного метода. В вашем случае вспомогательный метод по умолчанию будет basic_app_engineтак что вы можете позвонить basic_app_engine.new_post_path в ваших взглядах или помощниках.

Если вы хотите, вы можете установить имя одним из двух способов.

# in engine/lib/basic_app/engine.rb:
module BasicApp
  class Engine < ::Rails::Engine
    engine_name 'basic'
  end
end

или же

# in app/config/routes.rb:
mount BasicApp::Engine => '/app', :as => 'basic'

В любом случае, вы можете позвонить basic.new_posts_path в ваших взглядах или помощниках.

По-другому

Другой вариант - не использовать установленный движок, а вместо этого заставить движок добавлять маршруты непосредственно в приложение. Высокое напряжение Thoughtbot делает это. Мне не нравится это решение, потому что оно может вызвать конфликты пространства имен, когда вы добавляете много движков, но оно работает.

# in engine/config/routes.rb
Rails.application.routes.draw do
  resources :posts, :path => '' do
                resources :post_comments
                resources :post_images
  end
end

# in app/config/routes.rb:
# (no mention of the engine)

На Рельсах 4 engine_name Директива не работает для меня.
Чтобы получить доступ к именованному маршруту, определенному в маршрутах движка, из собственного представления или контроллера движка, я в конечном итоге использовал подробный

BasicApp::Engine.routes.url_helpers.new_post_path

Я рекомендую определить простой вспомогательный метод, чтобы сделать его более удобным

# in /helpers/basic_app/application_helper.rb

module BasicApp::ApplicationHelper
  def basic_app_engine
    @@basic_app_engine_url_helpers ||= BasicApp::Engine.routes.url_helpers
  end
end

С этим на месте теперь вы можете использовать

basic_app_engine.new_post_path

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

main_app.root_path

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

MyApp::Engine.routes.url_helpers.new_post_path

XXX::Engine.routes.url_helpers.public_path

Другие вопросы по тегам