Question

Je travaille sur une application Ruby sur Rails 3 (.0) qui utilise un moteur Rails. Cependant, dans mon application locale, je souhaite remplacer l'un des itinéraires fournis par le moteur Rails.

À partir du moteur config / routes.rb:

match 'their_named_route' => 'controller#action', :as => 'the_route'

À partir de mon application config / routes.rb:

match 'my_named_route' => 'controller#action', :as => 'the_route'

Cependant, lorsque j'inspecte les itinéraires, les deux semblent être actifs (et leur itinéraire semble "gagner", au moins dans les contrôleurs de moteur)

$ rake routes
the_route  /my_named_route(.:format)    {:controller=>"controller", :action=>"action"}
the_route  /their_named_route(.:format) {:controller=>"controller", :action=>"action"}

Existe-t-il un bon moyen de forcer la route nommée de ma demande locale pour prendre la priorité?

Était-ce utile?

La solution

J'ai peur qu'il n'y ait pas de moyen aussi simple. Les itinéraires sont définis dans lib/action_dispatch/routing/mapper.rb:271, qui appelle add_route sur l'ensemble de routes (défini dans rack-mount-0.6.14/lib/rack/mount/route_set.rb, et en ligne 71 Le nom est joint). Il n'y a pas de méthode supprimée_route et l'itinéraire du moteur est ajouté en dernier. Vous pouvez ajouter votre itinéraire manuellement après l'initialisation de l'application avec rails.Application.Routes.Draw au lieu de l'avoir dans Routes.rb, ou vous pouvez corriger le moteur.

Autres conseils

Je l'ai contourné en déplaçant les routes de mon moteur de config / routes.rb vers une méthode de classe dans la classe moteur elle-même:

module MyEngine
  class Engine < Rails::Engine
    def self.routes
      MyRailsApp::Application.routes.draw do
        resources :products
      end
    end
  end
end

puis dans le fichier de routes de l'application de base:

MyRailsApp::Application.routes.draw do
  # Routes for base app including the ones overriding MyEngine::Engine.

  MyEngine::Engine.routes
end

Je peux alors remplacer avec plaisir tous les itinéraires de l'application de base avec ceux du moteur.

Notez que les itinéraires primordiaux doivent être définis avant les itinéraires remplacés, car les routes définies précédentes ont priorité plus tard.

Il n'y a aucun moyen de remplacer un itinéraire dans un moteur. Au lieu de cela, vous devez définir une route de remplacement. Vous pouvez le faire en appelant prepend Sur le routeur du moteur:

An::Engine.routes.prepend do
  root :to => "somewhere#action"
end

Si l'espace de noms du moteur est isolé, cela utilisera le SomewhereController De l'intérieur de l'espace de noms du moteur. Sinon, il utilisera le typique SomewhereController.

Si vous souhaitez remplacer un itinéraire pour retourner un 404, la meilleure façon à laquelle je peux penser est de rediriger vers une page 404:

match "/route_goes_here" => redirect("/404")

Vous avez besoin d'ajouter un crochet initial sur config / application.rb, comme ceci:

class Application < Rails::Application

  config.encoding = "utf-8"

  ...

  initializer :add_routing_paths do |app|
    their_routes_path = app.routes_reloader.paths.select{|path| path =~ /DIR/}.first
    app.routes_reloader.paths.delete(their_routes_path)
    app.routes_reloader.paths.unshift(their_routes_path)
  end
end

Il s'agit d'abord de chargement de roues.rb de votre moteur et vous pouvez remplacer leurs itinéraires.

Vous pouvez prétendre les itinéraires comme suggéré par Ryan Bigg ci-dessus. J'ai trouvé que pour remplacer l'assistant d'itinéraire nommé avec mon itinéraire personnalisé, je dois appeler append à la place de prepend, ainsi:

An::Engine.routes.append do
  root :to => "somewhere#action"
end

Sinon, l'application contient à la fois les itinéraires et l'assistance nommée pour le routeur du moteur est la dernière définition, et donc celle qui est appliquée.

Les règles de routage définies dans les itinéraires.rb sont appliquées en haut vers le bas jusqu'à ce qu'une correspondance soit trouvée. J'ai pu remplacer l'itinéraire défini dans le moteur monté simplement en déplaçant la règle de priorité supérieure au dessus la ligne où le moteur est monté. Alors,

get 'about', controller: 'static', action: 'about', as: 'about'
mount My::Engine => '/'

Résultats dans le routage de l'application / environ / demandes à (dans ce cas) le contrôleur statique, alors que:

mount My::Engine => '/'
get 'about', controller: 'static', action: 'about', as: 'about'

Résultats dans le routage de l'application / environ / Demandes sur l'itinéraire défini dans le moteur monté.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top