8
votes

Rails - y compris des associations avec des conditions dynamiques

Étant donné un modèle d'école et un modèle d'étudiant avec l'école ayant une relation has_many à l'étudiant: xxx

où actif_year_id est une méthode définie dans le modèle d'école, je rencontre une erreur qui "actif_year_id est indéfini" lorsque vous appelez: xxx

La condition fonctionne bien lorsque je le fais, disons, xxx seulement lorsque J'essaie d'utiliser Inclus puis-je obtenir cette erreur. Est-ce le bon comportement. Sinon, qu'est-ce que je fais mal et comment puis-je réparer?

Utilisation des rails 3.0.9, REE 1.8.7.


3 commentaires

serait génial d'entendre si vous avez trouvé une solution autre que vous n'entraînez-vous que les inclusions.


J'ai le même problème: Stackoverflow.com/Questtions/10502307/...


@Vijaydev dans mon exemple répliqué le code école.Où (: id => 10) .Students Autres exception qui est méthode non définie Les étudiants 'pour # `parce que la valeur de retour de est un objet relationnel. Êtes-vous sûr que votre code fonctionne et ce n'est pas école.find (10) .Students (qui fonctionne comme prévu)


4 Réponses :


0
votes

Cela devrait être un commentaire mais il n'y a pas assez de place.

SO: P>

School.where(:active => true).includes(:students)


2 commentaires

Je pense que la réponse implicite de @codeglot peut être que vous devez étiqueter sur un . Students à votre School.where (: actif => vrai). Enclut (: les étudiants) Requête.


@codeglot: Je comprends qu'ils sont deux choses différentes. Je dis que l'erreur ne se produit que lorsque vous utilisez Inclus. Lorsque je fais la requête d'inclure, les rails font une autre requête pour les étudiants, à droite. Dans cette requête, j'ai besoin de l'état dans la procédure pour être annexé.



5
votes

Je pense que cela n'est pas possible de réaliser car le contexte de l'endroit où le PROC est exécuté est différent en fonction de la manière dont elle s'appelle. J'ai fabriqué une application de base avec vos modèles et c'est ce qui se passe lorsque vous appelez les différentes méthodes ( AP est-ce ): xxx

Lorsque vous appelez les élèves de la relation d'une instance d'école, le contexte de la procédure est l'instance donnée école afin qu'il réponde au actif_year_id méthode xxx

mais lorsque vous appelez la relation inclut le contexte est différent et ce que le procédé reçoit comme auto est Student Classe , donc il ne répond pas à cette méthode et cela déclenchera l'erreur xxx

Je pense qu'une relation has_many ne peut pas être utilisée avec ce type de procédé qui s'appuie sur une méthode d'instance d'une instance d'école. Je pense que la seule façon d'utiliser des procs comme décrit ici est de calculer une condition Au moment de l'exécution qui n'implique pas les méthodes d'instance (conditions de temps, où avec des données de modèles non liés, etc.).

En outre le School.AllUt (: les étudiants). Mon exemple ne peut pas fonctionner car il devrait appeler la méthode active_year_id sur chaque instance école (qui doit être extraite à partir de la DB avant que la notice puisse être évaluée ) et donc disparaître l'effet du comportement .

tout cela est valide si le actif_year_id est une méthode calculée définie dans École classe basée sur des données d'instance. Au lieu de cela si le actif_year_id n'est pas une méthode, mais un champ (une colonne de base de données) de la classe classe que vous pouvez jouer avec Joignons et Scopes pour obtenir un résultat similaire à ce que vous voulez réaliser, mais il doit être codé à la main.


0 commentaires

10
votes

Ceci est un peu vieux, mais je vois beaucoup la question et je n'ai vu aucune solution satisfaisante. L'ajout d'une condition comme celle-ci est essentiellement équivalente à la création d'une association avec deux clés publiques / privées.

@fabio a raison de dire " le contexte de l'endroit où le procédé est exécuté est différent de la manière dont il est appelé. "Cependant, je pense que vous pouvez surmonter le problème" active_year_id est indéfini "problème"

dans l'exemple: xxx

Le problème est que dans certaines situations , la procédure est exécutée dans le contexte d'un objet scolaire particulier et parfois en tant qu'associations Activerecord :: Associations :: JOINDEPENDENCE :: AKIALAssociation. J'ai résolu ceci en utilisant un procédé légèrement plus compliqué, comme celui-ci: xxx

Donc, lorsque la condition est calculée pour un objet scolaire réel, auto répond à l'accesseur d'attributs actif_year_id et vous pouvez fournir un hachage comme condition (qui fonctionne plus bien qu'une simple chaîne interpolée pour la création d'objets associés, etc.)

lorsque le contexte ne présente pas auto < / fort> comme un objet scolaire réel, (qui, comme vous l'avez noté, surveille lorsqu'il est appelé à l'aide d'une clause Inclure , par exemple), le contexte est une association et la forme de chaîne de la condition fonctionne simplement bien Utilisation des noms de champ plutôt que des valeurs.

Nous avons trouvé cette solution utilisons l'association dynamique avec succès.


1 commentaires

Selon la question initiale, cette solution fonctionne pour les rails 3. Cela ressemble à des rails 4 aura quelques nouvelles options d'association (ou au moins quelques nouvelles signatures de méthodes.)



0
votes

FYI Vous pouvez accéder à la collection actuelle L'inclusion est appelée ... Cela pourrait aider dans certains cas: xxx


0 commentaires