Учитывая следующие ассоциации, мне нужно сослаться на Question
то, что a Choice
прикреплено к Choice
модели. Я пытался использовать belongs_to :question, through: :answer
для выполнения этого действия.
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
я осознаю
NameError неинициализированная константа
User::Choice
когда я пытаюсь сделать current_user.choices
Он отлично работает, если я не включу
belongs_to :question, :through => :answer
Но я хочу использовать это, потому что хочу иметь возможность validates_uniqueness_of
Я, наверное, упускаю из виду что-то простое. Любая помощь будет оценена.
Ответы:
У
belongs_to
ассоциации не может быть:through
выбора. Вы лучше кэшированиеquestion_id
наChoice
и добавления уникального индекса к таблице (особенно потому , чтоvalidates_uniqueness_of
склонна к условиям гонки).Если вы параноик, добавьте настраиваемую проверку
Choice
, подтверждающуюquestion_id
совпадение ответа , но похоже, что конечному пользователю никогда не следует предоставлять возможность отправлять данные, которые могут создать такое несоответствие.источник
Вы также можете делегировать:
class Company < ActiveRecord::Base has_many :employees has_many :dogs, :through => :employees end class Employee < ActiveRescord::Base belongs_to :company has_many :dogs end class Dog < ActiveRecord::Base belongs_to :employee delegate :company, :to => :employee, :allow_nil => true end
источник
Просто используйте
has_one
вместоbelongs_to
вашего:through
, например:class Choice belongs_to :user belongs_to :answer has_one :question, :through => :answer end
Не связано, но я бы не решился использовать validates_uniqueness_of вместо использования правильного уникального ограничения в вашей базе данных. Когда вы делаете это в рубине, у вас возникают условия гонки.
источник
autosave: false
не установлен.Мой подход заключался в создании виртуального атрибута вместо добавления столбцов базы данных.
class Choice belongs_to :user belongs_to :answer # ------- Helpers ------- def question answer.question end # extra sugar def question_id answer.question_id end end
Этот подход довольно прост, но требует компромиссов. Требуется загрузка Rails
answer
из базы данных, а затемquestion
. Это можно оптимизировать позже, загружая нужные вам ассоциации (т.е.c = Choice.first(include: {answer: :question})
), однако, если такая оптимизация необходима, то ответ stephencelis, вероятно, будет лучшим решением для производительности.Есть время и место для определенного выбора, и я думаю, что этот выбор лучше при прототипировании. Я бы не стал использовать его для производственного кода, если бы не знал, что он предназначен для нечастого использования.
источник
Таким образом, вы не можете вести себя так, как хотите, но можете делать то, что вам нравится. Вы хотите уметь делать
Choice.first.question
то, что я делал в прошлом, примерно так
class Choice belongs_to :user belongs_to :answer validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ] ... def question answer.question end end
таким образом теперь вы можете задать вопрос по выбору
источник
Похоже, что вам нужен Пользователь, у которого много вопросов.
У вопроса много ответов, один из которых - выбор пользователя.
Это то, что вам нужно?
Я бы смоделировал что-то подобное в следующих строках:
class User has_many :questions end class Question belongs_to :user has_many :answers has_one :choice, :class_name => "Answer" validates_inclusion_of :choice, :in => lambda { answers } end class Answer belongs_to :question end
источник
has_many :choices
Создает объединение имениchoices
, а неchoice
. Попробуйте использоватьcurrent_user.choices
вместо этого.См. Документацию ActiveRecord :: Associates для получения информации о
has_many
магии.источник