我有一些用户参加测验。我跟踪他们选择的结果。我需要弄清楚如何让他们改变他们的测验提交。如果我只关联答案,他们会回答两次问题。建立数据很复杂,ActiveRecord是否提供了解决这个问题的方法?
整个示例将在独立文件中运行。
这是我的架构:
require 'active_record'
ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
ActiveRecord::Schema.define do
self.verbose = false
create_table :users do |t|
t.string :name
end
create_table :questions do |t|
t.string :name
end
create_table :question_results do |t|
t.string :name
t.integer :question_id
end
create_table :question_results_users do |t|
t.integer :user_id
t.integer :question_result_id
end
end
这是我的模特:
class User < ActiveRecord::Base
has_and_belongs_to_many :question_results
has_many :questions, through: :question_results
end
class Question < ActiveRecord::Base
has_many :question_results
end
class QuestionResult < ActiveRecord::Base
belongs_to :question
has_and_belongs_to_many :users
end
让我们提出三个问题和一些答案:
Question.create! name: "What's your favourite movie?" do |question|
question.question_results.build name: 'Gattaca'
question.question_results.build name: 'Super Troopers'
end
Question.create! name: 'Who do you want to be president?' do |question|
question.question_results.build name: 'Barack Obama'
question.question_results.build name: 'Mitt Romney'
question.question_results.build name: 'Mickey Mouse'
end
Question.create! name: "What's your favourite colour?" do |question|
question.question_results.build name: 'black'
question.question_results.build name: 'green'
end
让我们成为一个用户:
jim = User.create! name: 'Jim'
jim.question_results << QuestionResult.find_by_name('Gattaca')
jim.question_results << QuestionResult.find_by_name('Barack Obama')
jim.question_results << QuestionResult.find_by_name('black')
jim.question_results # => [#<QuestionResult id: 1, name: "Gattaca", question_id: 1>, #<QuestionResult id: 3, name: "Barack Obama", question_id: 2>, #<QuestionResult id: 6, name: "black", question_id: 3>]
jim.question_results.map(&:question) # => [#<Question id: 1, name: "What's your favourite movie?">, #<Question id: 2, name: "Who do you want to be president?">, #<Question id: 3, name: "What's your favourite colour?">]
现在吉姆改变了主意,他决定自己喜欢超级战队并且不想投票,但他仍然喜欢黑人。如何在没有多次回答问题的情况下更新此内容?
# pretend we're in a controller here (also note that I can change the format of the data, if there is something more convenient)
posted_from_form = {
questions: {
Question.all[0].id => 'Super Troopers',
Question.all[1].id => '',
Question.all[2].id => 'black',
}
}
答案 0 :(得分:0)
首先,我们可以更改数据的格式,以便结果采用id格式而不是名称格式:
posted_from_form = {
questions: {
Question.all[0].id => QuestionResult.find_by_name('Super Troopers').id.to_s,
Question.all[1].id => '',
Question.all[2].id => QuestionResult.find_by_name('black').id,
}
}
然后你可以直接设置id,ActiveRecord将处理所有的复杂性:
jim.question_result_ids = posted_from_form[:questions].values # => ["2", "", 6]
jim.question_results # => [#<QuestionResult id: 6, name: "black", question_id: 3>, #<QuestionResult id: 2, name: "Super Troopers", question_id: 1>]