Spécification de la clé étrangère dans une has_many: par rapport
-
21-09-2019 - |
Question
Je les trois modèles suivants: utilisateur, projet et affectation
. A Projets has_many
utilisateur par le biais d'une cession. Toutefois, la cession a fait deux clés étrangères qui se rapportent à un utilisateur. user_id
(représentant l'utilisateur qui a été attribué le projet) et completer_id
(représentant l'utilisateur qui a terminé le projet)
Souvent, user_id
et completer_id
seront les mêmes (si l'utilisateur qui a été attribué au projet le complète). Cependant, si un autre utilisateur le complète, user_id et completer_id seront différentes.
Dans mon modèle d'utilisateur, je donne les résultats suivants:
class User < ActiveRecord::Base
has_many :assignments
has_many :incomplete_assignments, :class_name => 'Assignment',
:conditions => 'completer_id IS NULL'
has_many :completed_assignments, :class_name => 'Assignment',
:foreign_key => 'completer_id'
# this is the important one
has_many :incomplete_projects,
:through => :assignments,
:source => :project,
:conditions => 'completer_id IS NULL'
end
Je voudrais faire une autre association, appelée :completed_projects
, qui utilise completer_id
comme la clé étrangère pour l'utilisateur dans le modèle :through
, plutôt que :user_id
. Est-il possible de le faire?
Et, en aparté, je suis au courant de l'option :foreign_key
. Cependant, cette option est ignorée lors de l'utilisation :through
, donc je voudrais savoir s'il y a une façon de le faire sans elle.
Enfin, je dois mentionner que je suis ouvert à d'autres conceptions, si elle ne peut se faire de cette façon et que quelqu'un peut penser à une meilleure façon.
La solution
Vous pouvez toujours utiliser SQL pour la sélection si ActiveRecord ne peut pas exprimer facilement la relation de la boîte:
has_many :completed_projects,
:class_name => "Project",
:finder_sql => 'SELECT p.* FROM projects p ' +
'INNER JOIN assignments a ON p.id=a.project_id ' +
'INNER JOIN users u on u.id=a.completer_id ' +
'WHERE u.id=#{id}'
Autres conseils
Avez-vous d'autres méta-données dans votre table de missions?
Sinon, je voudrais simplement utiliser HABTM et ajouter le completer_id à la table des projets à la place, il est logique de vivre là-bas de toute façon.
Si vous avez besoin / veulent utiliser has_many: à travers vous pouvez regarder à l'aide named_scopes (version Rails permet) pour que vous puissiez dire user.projects.completed
et user.projects.incomplete