#ruby-on-rails
#ruby-on-rails
Вопрос:
Впервые создаю что-либо с Ruby on Rails и немного теряюсь при реализации «has_many through».
В этом приложении у меня есть вопросы, DailyQuestionSets (на каждый день будет один DailyQuestionSet) и DailyQuestions (таблица ссылок «многие ко многим», так что в DailyQuestionSets может быть несколько вопросов.
(Я понимаю, что эти названия таблиц / моделей плохие, любые предложения по улучшению приветствуются 🙂
Я застрял на этапе создания метода в приложении DailyQuestionSet с именем get_today_dailyquestionset, который обращается к базе данных, чтобы узнать, существует ли DailyQuestionSet уже на этот день, если это не так, то создайте его и верните его свойство .questions, заполненное всеми вопросами из базы данных.
(позже я изменю это с получения всех вопросов на выбор 3 случайных вопросов каждый день)
class Question < ApplicationRecord
has_many :dailyquestions, foreign_key: 'dailyquestion_id'
has_many :dailyquestionsets, :through => :dailyquestions
default_scope -> { order(created_at: :desc) }
end
class DailyQuestion < ApplicationRecord
belongs_to :daily_question_set
belongs_to :question
end
class DailyQuestionSet < ApplicationRecord
has_many :daily_questions, foreign_key: 'question_id'
has_many :questions, :through => :daily_questions, :source => :question
def self.get_today_dailyquestionset
@dailyquestionset_list = DailyQuestionSet.where('posed_date BETWEEN ? AND ?', DateTime.now.beginning_of_day, DateTime.now.end_of_day).all
if @dailyquestionset_list.count == 0
@dailyquestionset = DailyQuestionSet.new(posed_date: DateTime.now)
@dailyquestionset.save
end
@questionlist = Question.all
@questionlist.each do |q|
@dailyquestionset.questions << q
end
return @dailyquestionset_list[0]
end
end
Я получаю эту ошибку, которую я интерпретирую как означающую, что объекты вопроса возвращаются из вопроса.у всех нет связанного с ними DailyQuestionSet. Что имеет смысл. Но я не могу найти способ создать отношение «многие ко многим» для каждого вопроса, прежде чем добавлять его в .массив вопросов.
ERROR["test_create_daily_daily_question_set_if_not_already_existing", DailyQuestionSetTest, 1.0837379119993784]
test_create_daily_daily_question_set_if_not_already_existing#DailyQuestionSetTest (1.08s)
ActiveRecord::RecordInvalid: ActiveRecord::RecordInvalid: Validation failed: Daily question set must exist
app/models/daily_question_set.rb:20:in `block in get_today_dailyquestionset'
app/models/daily_question_set.rb:19:in `get_today_dailyquestionset'
test/models/daily_question_set_test.rb:11:in `block in <class:DailyQuestionSetTest>'
Комментарии:
1. Вы уверены
@dailyquestionset.save
, что возвращение верно? возможно, какая-то ошибка не позволила сохранить его, поэтому нет идентификатора. И, если count> 0, вы никогда не устанавливаете@dailyquestionset
Ответ №1:
Да, belongs_to проверяет, существует ли связь. Вы должны добавить необязательный: true, если вы этого не хотите
class DailyQuestion < ApplicationRecord
belongs_to :daily_question_set, optional: true
belongs_to :question, optional: true
end
https://github.com/rails/rails/issues/34454
Вы должны это проверить
@dailyquestionset.save
возвращает значение true, в противном случае проверка, возможно, не прошла. Или используйте save! чтобы вызвать исключение.
Кроме того, Если @dailyquestionset_list.count > 0
, то @dailyquestionset
равно нулю.
п.д.: рад помочь, если вы предоставите больше информации п.д.д.: в
@dailyquestionset_list = DailyQuestionSet.where('posed_date BETWEEN ? AND ?', DateTime.now.beginning_of_day, DateTime.now.end_of_day).all
Я думаю, что так и должно быть posted_dated
и
@dailyquestionset = DailyQuestionSet.new(posed_date: DateTime.now)
Но это зависит от схемы.
Комментарии:
1. Большое спасибо за супер полезные советы! Я исправил некоторые очевидные ошибки, на которые вы указали 🙂 например, проверил @dailyquestionset на nil и изменил на @dailyquestionset.save! чтобы убедиться, что сохранение posed_date на самом деле не является опечаткой, просто мое имя столбца базы данных со странным именем для того, когда был задан набор вопросов, я попытался добавить optional: true к модели DailyQuestion, но затем я получаю сообщение об ошибке «метод. вопросы не определены» Больше никаких мыслей, которые наиболее ценятся!
2. Кроме того, меня немного смущает одна вещь: как эта таблица ссылок DailyQuestions фактически используется в коде модели. Я вижу добавление вопросов в DailyQuestionSet, но на самом деле это таблица DailyQuestions, которая управляет отношением «многие ко многим». Итак, если у меня есть существующий вопрос и DailyQuestionSet, какой код был бы правильным, чтобы связать их?
3. Вы должны начать использовать byebug. Это отладочный камень, который позволяет вам остановить код прямо перед ошибкой, чтобы вы могли проверить переменные и глубже взглянуть на то, что происходит. Так что, если вы получаете «метод . ошибка «Вопросы не определены», тогда @dailyquestionset — это не то, что вы думаете. github.com/deivid-rodriguez/byebug
4. Что касается вашего другого вопроса: ключевым моментом здесь является то, что у вас есть ассоциация has_many : through . Итак, когда вы добавляете вопрос в DailyQuestionSet и сохраняете его, rails создает объект DailyQuestion, который связывает вопрос и DailyQuestionSet. guides.rubyonrails.org /…