Die Angabe der Fremdschlüssel in einer has_many: durch Beziehung
-
21-09-2019 - |
Frage
Ich habe die folgenden drei Modelle:. Benutzer, Projekt und Zuordnung
Ein Benutzer has_many
Projekte durch eine Zuweisung. Allerdings Zuordnung tatsächlich hat zwei Fremdschlüssel, die auf einen Benutzer beziehen. user_id
(die den Benutzer, der das Projekt zugewiesen wurde) und completer_id
(die den Benutzer, der das Projekt abgeschlossen)
Oft user_id
und completer_id
werden das gleiche sein (wenn der Benutzer, der das Projekt abgeschlossen ist zugewiesen wurde). Wenn jedoch ein anderer Benutzer es abgeschlossen ist, user_id und completer_id wird anders sein.
In meinem User-Modell, ich habe folgende:
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
Ich möchte einen anderen Verein machen, genannt :completed_projects
, die completer_id
als Fremdschlüssel für den Benutzer im :through
Modell verwendet, anstatt :user_id
. Ist es möglich, dies zu tun?
Und wie nebenbei bemerkt, ich bin mir der :foreign_key
Option. Allerdings wird diese Option ignoriert, wenn :through
verwenden, so würde ich gerne wissen, ob es eine Möglichkeit, dies zu tun, ohne es.
Schließlich sollte ich erwähnen, dass ich offen bin zu anderen Designs, wenn es nicht so gemacht werden kann, und kann jemand einen besseren Weg denken.
Lösung
Sie können immer SQL verwenden für die Auswahl, wenn Active nicht leicht die Beziehung ausdrücken aus dem Kasten heraus:
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}'
Andere Tipps
Haben Sie andere Metadaten in Ihrer Zuweisungen Tisch?
Wenn ich nicht einfach HABTM verwenden würde und die completer_id zu den Projekten Tabelle hinzufügen statt, macht es Sinn, es trotzdem zu leben.
Wenn Sie brauchen / wollen has_many verwenden: durch Sie bei Verwendung named_scopes (Rails-Version erlaubt) aussehen könnte, so dass Sie user.projects.completed
und user.projects.incomplete