Названные маршруты в навесных рельсах двигателя
Я делаю небольшой рельсовый двигатель, который я монтирую так:
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