23

J'ai une application Rails 3 avec plusieurs moteurs contenant des fonctionnalités supplémentaires. Chaque moteur est un service distinct auquel les clients peuvent acheter un accès. J'ai cependant un problème avec les routes des moteurs qui ne sont pas facilement accessibles aux contrôleurs et aux vues.Comment puis-je rendre les routes d'un moteur Rails 3 disponibles pour l'application hôte?

contrôleur

:

class ClassroomsController < ApplicationController 
    .. 
    respond_to :html 

    def index 
    respond_with(@classrooms = @company.classrooms.all) 
    end 

    def new 
    respond_with(@classroom = @company.classrooms.build) 
    end 

    .. 
end 

app/views/classrooms/new.html.haml:

= form_for @classroom do |f| 
    .. 
    f.submit 

config/routes.rb dans le moteur:

MyEngineName::Engine.routes.draw do 
    resources :classrooms 
end 

config/routes.rb dans l'application:

Seabed::Application.routes.draw do 
    mount MyEngineName::Engine => '/engine' 
    ... 
end 

lib/my_engine_name.rb dans le moteur:

module MyEngineName 
    class Engine < ::Rails::Engine 
    end 
end 

essayant d'aller à /classrooms/new résultats dans

NoMethodError in Classrooms#new 

Showing app/views/classrooms/_form.html.haml where line #1 raised: 
    undefined method `hash_for_classrooms_path' for #<Module:0x00000104cff0f8> 

et d'essayer d'appeler classrooms_path de toute autre vue des résultats dans la même erreur. Je peux cependant appeler le MyEngineName::Engine.routes.url_helpers.classrooms_path et le faire fonctionner. Je pense que j'ai peut-être mal défini les routes, mais je ne trouve pas d'autre moyen qui fonctionne.

J'ai essayé de lancer l'application avec Passenger (module autonome et Apache) et WEBrick (serveur rails). Utilisation des derniers Rails de Git (7c920631ec3b314cfaa3a60d265de40cba3e8135).

Répondre

25

changement config.routes dans votre moteur:

Rails.application.routes.draw do # NOT MyEngineName::Engine.routes.draw 
    resources :classrooms 
end 

La façon dont vous l'avez, les routes ne sont disponibles que dans l'espace de noms MyEngineName::Engine et non dans le reste de l'application des rails hôtes.

Il y avait un billet de blog avec plus d'informations, mais malheureusement il n'est plus disponible:

+0

Faire cela, retirer le support d'appel dans mes app-routes, et portée en-routes moteur ('scope '/ engine' do') et tout fonctionne. Merci beaucoup :) – PerfectlyNormal

+0

Cool, merci pour les informations sur les autres étapes nécessaires pour faire fonctionner les routes du moteur. – bowsersenior

+2

Pour Rails 3.1 et versions ultérieures, supprimez le paramètre 'map' dans le bloc (supprimez simplement toute la partie' | map | '). –

26

j'ai eu le même problème, et trouvé cela dans le documentation:

Puisque vous pouvez maintenant monter un moteur à l'intérieur des voies d'application, vous ne disposez pas d'un accès direct à son moteur url_helpers dans Application. Lorsque vous montez un moteur dans les routes d'une application, une aide spéciale est créée pour vous permettre de le faire.Considérons un tel scénario:

# config/routes.rb 
MyApplication::Application.routes.draw do 
    mount MyEngine::Engine => "/my_engine", :as => "my_engine" 
    get "/foo" => "foo#index" 
end 

Maintenant, vous pouvez utiliser l'assistant de my_engine dans votre application:

class FooController < ApplicationController 
    def index 
    my_engine.root_url #=> /my_engine/ 
    end 
end 
+0

pour le code dans le moteur, avez-vous besoin de préfixer les routes vers ses propres contrôleurs avec le nom du moteur? Ou pouvez-vous simplement utiliser 'classrooms_path' depuis l'intérieur du moteur? – Jwan622

+0

Jwan622, pour les routes propres, vous pouvez utiliser des aides sans préfixes. –