3

Bon, voici un exemple de scénario. Il y a une ressource étudiante resources :students, et les étudiants a et appartient à de nombreuses collections: resources :clubs, resources :majors, etc.Rails Suppression RESTful dans les ressources imbriquées

Nous pouvons mettre en place assez facilement nos routes ...

resources :clubs do 
    resources :students 
end 
resources :majors do 
    resources :students 
end 
resources :students do 
    resources :clubs 
    resources :majors 
end 

qui nous génère un tas des itinéraires standards RESTful

  • /clubs
  • /clubs /: id
  • /clubs /: club_id/st udents
  • /clubs /: club_id/étudiants /: id
  • /majors
  • /majors /: id
  • /majors /: major_id/étudiants
  • /majors /: major_id/étudiants /: id
  • /étudiants
  • /étudiants /: id
  • /étudiants /: student_id/clubs
  • /étudiants /: student_id/clubs /: id
  • /étudiants /: student_id/majors
  • /étudiants /: student_id/majors /: id

Alors, voici ma question. Avec la sémantique REST, comment supprimer une majeure pour un étudiant? Le fait de parcourir les élèves sous un /majors/:major_id/students/:id majeur montrerait cet étudiant dans la «collection» de la majeure. Mais la route pour supprimer un: id, pointe à StudentsController#destroy, ce qui supprimerait complètement l'étudiant. Oups! Alors peut-être que nous allons dans l'autre sens, et effectuer DELETE sur la ressource au /students/:student_id/majors/:id et bien maintenant UnderwaterBasketweaving n'est plus offert à cette école ... Oups! Maintenant, nous pouvons définir la méthode destroy de ClubsController, MajorsController, ou StudentsController pour rechercher club_id, major_id, ou student_id, mais disons que nous voulons aussi ajouter Fraternities et GraduatingClasses, etc. commencerait à être composé d'énormes conditions de commutation cherchant à voir ce que param était présent ... et ensuite trouver la collection de la ressource supérieure et supprimer la ressource du bas, ou vice versa. Les modèles eux-mêmes devraient décider si elles se supprimer si elles ont plus de dossiers d'association ... « détruire » à cette ressource est devenue vraiment un terme mal approprié ...

est-il un moyen plus facile de le faire? Même les plugins restful rails populaires comme make_resourceful ou resource_controller souffleraient UnderwaterBasketweaving lors de son retrait de Joe's Majors ou complètement supprimer JohnDoe lors de son retrait de la principale UnderwaterBasketweaving. Il semblerait qu'il y ait un potentiel pour regarder l'association pour comprendre les effets désirés de la sémantique et ce que 'détruire' devrait faire.

Puis encore, est-ce que je regarde tout faux? Est-il pas UnderwaterBasketweaving -> Joe mais UnderwaterBasketweaving + Joe comme une seule ressource et ce que nous supprimons n'est vraiment pas Joe, ni UnderwaterBasketweaving, mais la ressource représentant la combinaison?Cependant, ce n'est pas facile quand les contrôleurs sont des étudiants et des majors, qui représentent en effet des ressources du même nom (MVC est devenu RV ... dans l'approche conventionnelle et ne développe pas de contrôleurs qui peuvent n'avoir aucun impact sur un modèle nom, ou le chemin pour l'atteindre) Donc vous seriez en train de supprimer un major ou un étudiant; Choisissez votre poison ...

Comment éviter la gestion de conditions à travers un graphe infini de ressources associées où la suppression n'est pas vraiment l'intention quand la suppression est voulue être dans le contexte d'une collection et ne pas se rapporter à sa singularité. ..? ... Y at-il un moyen pour l'objet ActiveRecord 'student' de savoir qu'il a reçu un message 'delete' dans une chaîne de méthodes commençant par l'objet 'majeur' AR?

Répondre

2

Eh bien, l'approche RESTful standard consiste à utiliser has_many :through et à générer un cotroller pour la ressource d'association. Nommer les ressources de l'association est toujours difficile, mais je vais essayer pour cet exemple.

resources :majors do 
    resources :studies 
    resources :students 
end 
resources :students do 
    resources :studies 
    resources :majors 
end 

Les modèles seraient bien sûr:

class Major < ActiverRecord::Base 
    has_many :studies 
    has_many :students, :through => :studies 
end 

etc. (commentaire si vous me voulez préciser)

Ensuite, pour un étudiant, vous ne serait pas SUPPRIMER il est associé @student.major mais son @student.studies.where :major => @major.

+0

Je pense que j'aime cette approche, sauf pour le volume qu'elle pourrait causer de l'excès de code. En dehors de mon exemple artificiel, j'aurais plus de 100 ressources d'association dans mon projet actuel. Il semble que nous rompons ici le paradigme 'C sur C' en configurant beaucoup de code supplémentaire où les idées sont déjà là dans le code d'association original (n'utilisant pas': through'); Bien que certains des plugins reposants comme 'make_resourceful' soient sympas, c'est parce qu'ils déplacent la sémantique de la relation dans l'espace du contrôleur, ce qui rendrait plus facilement possible le traitement logique du code méta-généré. – Andy

+0

De plus, vous n'auriez pas' resources: majors avoir beaucoup d'étudiants puisque ce n'est pas une ressource imbriquée sous votre paradigme (comme je le suis ...). La ressource imbriquée à chacun est la ressource d'association, ce qui résout définitivement le problème de la suppression du mauvais objet. La ressource d'association pourrait alors avoir des ressources imbriquées de ce à quoi sont liés les vrais modèles de domaine. Encore une fois, je l'aime, mais je m'inquiète des ressources excessives d'association à gérer. _Il est intéressant que nous ayons passé de la taxonomie hiérarchique à la promotion de plusieurs facettes, mais l'URL (RESTful) est toujours très hiérarchique_ – Andy

+0

Je ne suis pas sûr de suivre votre deuxième commentaire. Généralement dit 'has_many: through' se comporte exactement comme' has_and_belongs_to_many' sauf qu'il vous donne le contrôle sur l'association. Vous devrez donc générer les modèles pour ces associations. Cependant, vous pouvez gérer leur création et leur suppression dans d'autres contrôleurs. Voir 'accepte_nested_attributes_for'. Les greffons de contrôleurs sont sympas (j'utilise personnellement InheritedResources, mais dans de nombreux cas, vous devrez écrire vous-même le code (ou écrire une librairie qui résoud votre cas d'utilisation particulier) –

Questions connexes