web-dev-qa-db-fra.com

Routes nommées dans le moteur monté Rails

Je crée un petit moteur Rails que je monte comme ceci:

mount BasicApp::Engine => "/app"

En utilisant cette réponse j'ai vérifié que toutes les routes dans le moteur sont comme il se doit:

Cependant - lorsque je (à l'intérieur du moteur) je relie à une route nommée (définie à l'intérieur du moteur), j'obtiens cette erreur

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

L'exécution de "rake route" vérifie clairement que "new_post" doit être un chemin nommé, donc je n'ai aucune idée pourquoi Rails (3.1.0) ne peut pas le comprendre. Toute aide est la bienvenue.

mon config/route.rb (pour le moteur) ressemble à ceci

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

Je dois ajouter que c'est un moteur isolé. Cependant, des chemins comme main_app.root_path fonctionnent correctement - alors que root_path ne le fait pas

37
Markus

Le droit chemin

Je pense que la meilleure solution est d'appeler new_post_path sur le proxy de routes du moteur, qui est disponible comme méthode d'assistance. Dans votre cas, la méthode d'assistance sera par défaut basic_app_engine, pour que vous puissiez appeler basic_app_engine.new_post_path dans vos vues ou assistants.

Si vous le souhaitez, vous pouvez définir le nom de deux manières.

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

ou

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

Dans les deux cas, vous pouvez appeler basic.new_posts_path dans vos vues ou assistants.

Autrement

Une autre option consiste à ne pas utiliser de moteur monté et à demander au moteur d'ajouter les routes directement à l'application. HighVoltage de Thoughtbot le fait. Je n'aime pas cette solution car elle est susceptible de provoquer des conflits d'espace de noms lorsque vous ajoutez de nombreux moteurs, mais cela fonctionne.

# 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)
57
James A. Rosen

Sur Rails 4 le engine_name directive n'a pas fonctionné pour moi.
Pour accéder à une route nommée définie dans les routes du moteur à partir de la vue ou du contrôleur du moteur, j'ai fini par utiliser le mot détaillé

BasicApp::Engine.routes.url_helpers.new_post_path

Je recommande de définir une méthode d'aide simple pour rendre cela plus utilisable

# 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

Avec ceci en place, vous pouvez maintenant utiliser

basic_app_engine.new_post_path

Si vous avez besoin d'accéder à votre assistant d'application principal à partir du moteur, vous pouvez simplement utiliser main_app:

main_app.root_path
9
Epigene

utilisez ce qui suit dans votre application pour accéder aux itinéraires du moteur

MyApp::Engine.routes.url_helpers.new_post_path
3
edrich13