J'ai deux modèles générés par un échafaudage, étudiant b> et classe b>. Ils ont une relation plusieurs à plusieurs mises en œuvre avec HAS_AND_BELONGS_TO_MANY. Quelle est la meilleure façon de faire cela? P>
J'aimerais pouvoir changer quelle classe forte> ES A STRAND> Student Strong> est dans aussi bien que ce que étudiant strong> S est en train de prendre chaque classe
Comment puis-je faire cela repose?
Si je retire une classe
Mon autre pensée est juste d'appeler une certaine action dans les étudiants_controller (disons, retirer_class) et transmettre l'identifiant de la classe
5 Réponses :
Si cela est vraiment reposé, vous changeriez simplement la classe et l'élève en même temps, en ajoutant la relation à la fois ou en le supprimant des deux. Après avoir vérifié que le modèle téléchargé était auto-cohérent, vous le comparez ensuite à l'encontre de la précédente et de faire les changements nécessaires. Si ce changement est entraîné par catégorie ou que l'étudiant devient un détail de mise en œuvre. P>
Deux autres options: p>
Vous pouvez rendre les informations sur l'état de repos moins redondantes, en laissant la classe ou l'élève de la relation, mais cela ne correspond peut-être pas à vos besoins. P>
Vous pouvez également conserver les informations de relation des deux côtés, mais décidez que l'on est canonique. Ainsi, par exemple, si l'étudiant appartient à la classe, pas l'étudiant, alors tout changement à l'étudiant appartient à l'élève est ignoré. P>
Je préfère la première option, mais je pense que ceux-ci devraient être au moins pris en compte. P>
Je ne suis pas sûr de vouloir faire les deux de manière robuste. Vous auriez probablement plus de kilométrage en créant une relation de suppression en cascade entre les deux. p>
Voici une discussion sur Suppression de cascade sur les rails . p>
Vous pouvez avoir deux ressources imbriquées?
dépendez de savoir si vous avez un paramètres [: class_id] code> (veuillez ne pas dire que vous avez appelé votre classe modèle!) Ou si vous aviez un Params [: Student_ID] CODE> Vous pouvez dire lequel est l'objet que l'opération est appelée (voir Sample Création ci-jointe d'un côté): P> class SchoolClassController < ApplicationController
before_filter :get_school_class, :except => [:new, :create, :index]
before_filter :get_student
def create
get_school_class(false)
get_student(false)
if @school_class
if @student
(@school_class.students << @student)
else
redirect_to "/" and return
end
else
@school_class = SchoolClass.new(params[:school_class])
end
if @school_class.save
redirect_loc = @student ? student_school_class_path(@student, @school_class) : school_class_path(@student)
redirect_to redirect_loc and return
else
redirect_to "/"
end
end
private
def get_school_class(will_redirect=true)
begin
@school_class = SchoolClass.find(params[:id])
rescue AR::RNF
(redirect_to "/" and return false) if will_redirect
end
end
def get_student(will_redirect=true)
if params[:student_id]
begin
@student = Student.find(params[:student_id])
rescue AR:RNF
(redirect_to "/" and return false) if will_redirect
end
end
end
end
La touche pour résoudre ce problème consiste à identifier correctement la ressource que vous modifiez. Dans ce cas, la ressource que vous modifiez est la relation entre la classe et l'étudiant, que je me référerai comme une inscription code> code>.
Il est devenu habituel dans des rails d'utilisation une des idées clés pour Le repos est que des ressources reposantes n'ont pas besoin de cartographier des modèles. Vous devez créer un alors vous pouvez créer et supprimer vos relations comme: < / p> et vous pouvez créer des boutons pour ces actions comme: p> has_many : via code> préférentiellement à has_and_belongs_to_many code>. Vous voudrez peut-être modifier votre logique de domaine pour vous adapter à la coutume, mais vous pouvez également endommager la tendance, si vous êtes vraiment certain qu'aucune métadonnée n'a besoin d'être stockée sur la relation. P> inscrivez-vousController code> et ajoutez une ligne à config / routtes.rb: p> 1 code> sur La ligne ci-dessus agit comme un espace réservé où le : inscription_id code> devrait aller et est un peu de vinaigre syntaxique pour vous rappeler que vous collez la volonté du cadre des rails. P> P>
Merci, cela a très bien fonctionné avec deux changements mineurs: 1. Appeler @ Student.Courses.Destroy (Params [: Course_id]) m'a donné un ACTiverecord :: AssociationTyPamismatic, car il cherchait bien sûr et obtenu une chaîne. J'ai réparé cela en trouvant d'abord le bon parcours (@ étudiant.courses.find (Params [: cours de cours])), puis en supprimant cela. 2. Je ne veux pas détruire le cours, simplement supprimer l'association, donc j'ai utilisé un appel de suppression au lieu de détruire
Heureux que ça ait travaillé. J'ai mis à jour mon exemple pour refléter vos modifications.
Il existe une variété de méthodes ajoutées lorsqu'il indique un nombre élevé à plusieurs relations (17 à être exact) selon les rails 6.1.0 P>
Selon ce que vous recevez de votre extrémité frontale, étant l'objet d'un objet associé ou simplement leurs identifiants, vous voudrez appeler différentes méthodes: p>
Utilisation d'un tableau de l'ensemble des objets associés: I.e: @Student. classes = strong> new_student_classes_array p>
Recevoir une gamme de clés principales d'objets associés (Habituellement IDS): I.e: @Student. class_ids = strong> new_student_classes_array p> collection_plural = code> p>
Collection_singular_ids = code> P>