In Anbetracht der folgenden Assoziationen muss ich auf das verweisen Question
, Choice
durch das a aus dem Choice
Modell angehängt wird . Ich habe versucht zu verwendenbelongs_to :question, through: :answer
, diese Aktion auszuführen.
class User
has_many :questions
has_many :choices
end
class Question
belongs_to :user
has_many :answers
has_one :choice, :through => :answer
end
class Answer
belongs_to :question
end
class Choice
belongs_to :user
belongs_to :answer
belongs_to :question, :through => :answer
validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ]
end
ich bekomme
NameError nicht initialisierte Konstante
User::Choice
wenn ich es versuche current_user.choices
Es funktioniert gut, wenn ich das nicht einbeziehe
belongs_to :question, :through => :answer
Aber ich möchte das nutzen, weil ich das tun möchte validates_uniqueness_of
Ich übersehen wahrscheinlich etwas Einfaches. Jede Hilfe wäre dankbar.
Antworten:
Ein
belongs_to
Verein kann keine:through
Option haben. Du bist besser dran das Cachingquestion_id
aufChoice
und das Hinzufügen eines eindeutigen Index der Tabelle (vor allem , weilvalidates_uniqueness_of
zu Rennbedingungen anfällig).Wenn Sie paranoid sind, fügen Sie eine benutzerdefinierte Validierung hinzu,
Choice
die bestätigt, dass die Antwortquestion_id
übereinstimmt. Es scheint jedoch , dass dem Endbenutzer niemals die Möglichkeit gegeben werden sollte, Daten zu übermitteln, die zu einer solchen Nichtübereinstimmung führen würden.quelle
Sie können auch delegieren:
quelle
Verwenden Sie einfach
has_one
stattbelongs_to
in Ihrem:through
, wie folgt:Unabhängig, aber ich würde zögern, validates_uniqueness_of zu verwenden, anstatt eine geeignete eindeutige Einschränkung in Ihrer Datenbank zu verwenden. Wenn Sie dies in Rubin tun, haben Sie Rennbedingungen.
quelle
autosave: false
ist.Mein Ansatz war es, ein virtuelles Attribut zu erstellen, anstatt Datenbankspalten hinzuzufügen.
Dieser Ansatz ist ziemlich einfach, bringt jedoch Kompromisse mit sich. Es erfordert, dass Rails
answer
von der Datenbank geladen wird , und dannquestion
. Dies kann später optimiert werden, indem Sie die benötigten Assoziationen eifrig laden (zc = Choice.first(include: {answer: :question})
geladen werden ). Wenn diese Optimierung jedoch erforderlich ist, ist die Antwort von stephencelis wahrscheinlich eine bessere Leistungsentscheidung.Es gibt eine Zeit und einen Ort für bestimmte Entscheidungen, und ich denke, diese Wahl ist beim Prototyping besser. Ich würde es nicht für Produktionscode verwenden, wenn ich nicht wüsste, dass es sich um einen seltenen Anwendungsfall handelt.
quelle
Es hört sich so an, als ob Sie einen Benutzer haben möchten, der viele Fragen hat.
Die Frage hat viele Antworten, von denen eine die Wahl des Benutzers ist.
Ist es das, wonach du suchst?
Ich würde so etwas in diese Richtung modellieren:
quelle
Sie können also nicht das Verhalten haben, das Sie wollen, aber Sie können etwas tun, das sich so anfühlt. Sie möchten in der Lage sein zu tun
Choice.first.question
Was ich in der Vergangenheit getan habe, ist so etwas
Auf diese Weise können Sie jetzt eine Frage zur Auswahl stellen
quelle
Das
has_many :choices
erstellt eine Assoziation mit dem Namenchoices
, nichtchoice
. Versuchen Sie escurrent_user.choices
stattdessen.Siehe die Active :: Verbände Dokumentation für Informationen über über die
has_many
Magie.quelle