Étant donné les associations suivantes, je dois faire référence au Question
qui Choice
est attaché par le Choice
modèle. J'ai essayé d'utiliser belongs_to :question, through: :answer
pour effectuer cette action.
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
Je reçois
NameError Constante non initialisée
User::Choice
quand j'essaye de faire current_user.choices
Cela fonctionne bien, si je n'inclus pas le
belongs_to :question, :through => :answer
Mais je veux l'utiliser parce que je veux pouvoir faire le validates_uniqueness_of
J'oublie probablement quelque chose de simple. Toute aide serait appréciée.
Réponses:
Une
belongs_to
association ne peut pas avoir d':through
option. Vous feriez mieux de mettre en cache lequestion_id
onChoice
et d'ajouter un index unique à la table (surtout parce qu'ilvalidates_uniqueness_of
est sujet à des conditions de concurrence).Si vous êtes paranoïaque, ajoutez une validation personnalisée
Choice
qui confirme que la réponsequestion_id
correspond, mais il semble que l'utilisateur final ne devrait jamais avoir la possibilité de soumettre des données qui créeraient ce type d'incohérence.la source
Vous pouvez également déléguer:
la source
Utilisez simplement
has_one
au lieu debelongs_to
dans votre:through
, comme ceci:Sans rapport, mais j'hésiterais à utiliser validates_uniqueness_of au lieu d'utiliser une contrainte unique appropriée dans votre base de données. Lorsque vous faites cela en rubis, vous avez des conditions de course.
la source
autosave: false
soit définie.Mon approche était de créer un attribut virtuel au lieu d'ajouter des colonnes de base de données.
Cette approche est assez simple, mais s'accompagne de compromis. Il faut que Rails se charge à
answer
partir de la base de données, puisquestion
. Cela peut être optimisé plus tard en chargeant avec impatience les associations dont vous avez besoin (c'est-à-direc = Choice.first(include: {answer: :question})
), cependant, si cette optimisation est nécessaire, la réponse de stephencelis est probablement une meilleure décision de performance.Il y a un moment et un lieu pour certains choix, et je pense que ce choix est meilleur lors du prototypage. Je ne l'utiliserais pas pour le code de production à moins de savoir que c'était pour un cas d'utilisation peu fréquent.
la source
Cela ressemble à ce que vous voulez, c'est un utilisateur qui a de nombreuses questions.
La question a de nombreuses réponses, dont l'une est le choix de l'utilisateur.
C'est ce que vous recherchez?
Je modéliserais quelque chose comme ça dans le sens suivant:
la source
Vous ne pouvez donc pas avoir le comportement que vous souhaitez, mais vous pouvez faire quelque chose qui vous ressemble. Tu veux pouvoir faire
Choice.first.question
ce que j'ai fait dans le passé est quelque chose comme ça
de cette façon, vous pouvez maintenant appeler la question sur Choice
la source
Le
has_many :choices
crée une association nomméechoices
, nonchoice
. Essayez d'utiliser à lacurrent_user.choices
place.Consultez la documentation ActiveRecord :: Associations pour plus d'informations sur la
has_many
magie.la source