Mes vues Rails et les contrôleurs sont jonchées redirect_to
, link_to
et les form_for
appels de méthode. Parfois link_to
et redirect_to
sont explicites dans les chemins qu'ils lient (par exemple link_to 'New Person', new_person_path
), mais souvent les chemins sont implicites (par exemple link_to 'Show', person
).
J'ajoute un héritage de table unique (STI) à mon modèle (par exemple Employee < Person
), et toutes ces méthodes sont interrompues pour une instance de la sous-classe (par exemple Employee
); lorsque les rails s'exécutent link_to @person
, il se trompe avec undefined method employee_path' for #<#<Class:0x000001022bcd40>:0x0000010226d038>
. Rails recherche un itinéraire défini par le nom de classe de l'objet, qui est employé. Ces itinéraires d'employés ne sont pas définis et il n'y a pas de contrôleur d'employés, donc les actions ne sont pas définies non plus.
Cette question a déjà été posée:
- Chez StackOverflow , la réponse est de modifier chaque instance de link_to etc dans l'ensemble de votre base de code, et d'indiquer le chemin explicitement
- Sur StackOverflow à nouveau, deux personnes suggèrent d'utiliser
routes.rb
pour mapper les ressources de la sous-classe à la classe parente (map.resources :employees, :controller => 'people'
). La première réponse à cette même question SO suggère de transtyper chaque objet d'instance dans la base de code en utilisant.becomes
- Encore un autre chez StackOverflow , la meilleure réponse est dans le camp Do Repeat Yourself, et suggère de créer des échafaudages en double pour chaque sous-classe.
- Voici à nouveau la même question chez SO, où la première réponse semble tout simplement fausse (Rails magic Just Works!)
- Ailleurs sur le web, j'ai trouvé ce billet de blog où F2Andy recommande de modifier le chemin partout dans le code.
- Dans le billet de blog Héritage de table unique et routes RESTful chez Logical Reality Design, il est recommandé de mapper les ressources de la sous-classe vers le contrôleur de la superclasse, comme dans la réponse SO 2 ci-dessus.
- Alex Reisner a publié un héritage de table unique dans les rails , dans lequel il déconseille de mapper les ressources des classes enfants à la classe parente dans
routes.rb
, car cela ne détecte que les ruptures de routage delink_to
etredirect_to
, mais pas deform_for
. Il recommande donc plutôt d'ajouter une méthode à la classe parente pour que les sous-classes mentent sur leur classe. Cela semble bien, mais sa méthode m'a donné l'erreurundefined local variable or method `child' for #
.
Donc , la réponse qui semble la plus élégante et a le plus consensus (mais ce n'est pas tout ce que élégant, ni que beaucoup de consensus), est l'ajouter les ressources à votreroutes.rb
. Sauf que cela ne fonctionne pas pour form_for
. J'ai besoin de clarté! Pour distiller les choix ci-dessus, mes options sont
- mapper les ressources de la sous-classe au contrôleur de la superclasse dans
routes.rb
(et j'espère que je n'ai pas besoin d'appeler form_for sur aucune sous-classe) - Remplacer les méthodes internes des rails pour que les classes se mentent
- Modifiez chaque instance du code dans laquelle le chemin d'accès à l'action d'un objet est appelé implicitement ou explicitement, en modifiant le chemin ou en convertissant le type de l'objet.
Avec toutes ces réponses contradictoires, j'ai besoin d'une décision. Il me semble qu'il n'y a pas de bonne réponse. Est-ce un échec dans la conception des rails? Si tel est le cas, est-ce un bogue qui pourrait être corrigé? Ou si ce n'est pas le cas, j'espère que quelqu'un pourra me donner raison, me présenter les avantages et les inconvénients de chaque option (ou expliquer pourquoi ce n'est pas une option), laquelle est la bonne réponse et pourquoi. Ou y a-t-il une bonne réponse que je ne trouve pas sur le Web?