I'm still making online test program.
这是我的模特。
调查
class Survey < ActiveRecord::Base
belongs_to :user
has_many :questions, :dependent => :destroy
accepts_nested_attributes_for :questions, :reject_if => lambda {|a| a[:content].blank?}, :allow_destroy => true
问题:有一个is_correct列,表明学生是否得到了正确的答案。
class Question < ActiveRecord::Base
belongs_to :survey
has_many :answers, :dependent => :destroy
accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
答案:教师检查进行调查(测试)有正确的栏目,并且有学生标记参加考试的user_answer栏。
class Answer < ActviveRecord::Base
belongs_to :question
我在调查视图中使用show.html.erb上的考试界面。因此,如果学生填写此复选框并单击“提交”按钮,则可以获取其结果页面。但我无法在结果页面中显示结果。
这是我的调查控制员。
def grading
@survey = Survey.new
@survey.user_id = current_user.id
if @survey.questions.answers.user_answer and @survey.questions.answers.correct
@survey.questions.is_correct = true
end
redirect_to results_surveys_path(@survey)
end
def results
end
我看到的错误信息是[]的未定义方法`答案':ActiveRecord :: Relation'。我认为问答表之间有问题......
我认为自动评分很容易,但我错了。我不知道这个,除了你的帮助,我没有任何参考。
欢迎任何想法。
谢谢高级。
更新问题
这是另一个问题。
现在我可以访问嵌套对象了。(我想,我希望)但结果页面(调查视图中的result.html.erb)无法显示任何结果:“nil的未定义方法`名称:NilClass”
result.html.erb
<h1><%= @survey.name %></h1>
<h3><%= @survey.user.username %></h3>
正如我在previous link中所说,我在调查视图中的show.html.erb中有另一个form_tag。然后使用routes.rb重定向到结果页面。
resources :surveys do
collection do
get 'results'
end
end
我以为我可以在问题表中使用is_correct列显示结果页面。
我没有在调查控制器的结果方法中写任何东西。因为当我重定向页面时,我这样写了。这意味着在结果方法中使用@survey,不是吗?
redirect_to results_surveys_path(@survey)
以下是佣金路线的结果。
seriousin@classcasts:~/ClassCasts$ rake routes | grep survey
results_surveys GET /surveys/results(.:format) surveys#results
surveys GET /surveys(.:format) surveys#index
POST /surveys(.:format) surveys#create
new_survey GET /surveys/new(.:format) surveys#new
edit_survey GET /surveys/:id/edit(.:format) surveys#edit
survey GET /surveys/:id(.:format) surveys#show
PUT /surveys/:id(.:format) surveys#update
DELETE /surveys/:id(.:format) surveys#destroy
surveys_grading POST /surveys/grading(.:format) surveys#grading
seriousin@classcasts:~/ClassCasts$
我认为我的基本想法引起了我的所有问题。这是我的调查控制器。
class SurveysController < ApplicationController
def index
@surveys = Survey.all
end
def grading
@survey = Survey.new
@survey.user_id = current_user.id
@survey.questions.each do |question|
question.auto_check
end
redirect_to results_survey_path(@survey)
end
def results
@survey = Survey.where(params[:id])
end
def show
@survey = Survey.find(params[:id])
end
def new
@survey = Survey.new
end
def edit
@survey = Survey.find(params[:id])
end
def create
@survey = Survey.new(params[:survey])
@survey.user_id = current_user.id
end
def update
@survey = Survey.find(params[:id])
end
def destroy
@survey = Survey.find(params[:id])
@survey.destroy
end
end
如您所见,我在调查视图中使用显示页面作为另一种带有评分方法的输入表单。我可以在create方法中使用'@survey = Survey.new',这很有意义!但正如我在评分方法中写的那样,我认为它会产生另一项新的调查。 所以我需要更改那一行。你能帮帮我吗?
发送数据
行。当我在调查视图中提交_form.html.erb时,我可以发送这样的数据。
Parameters: {"id"=>"14", "survey"=>{"name"=>"The First Test!", "description"=>"This is the first test!", "questions_attributes"=>{"0"=>{"_destroy"=>"false", "id"=>"41", "content"=>"Question 2", "answers_attributes"=>{"0"=>{"_destroy"=>"false", "id"=>"66", "content"=>"Answer 2 of Question 2", "correct"=>"0"}, "1"=>{"_destroy"=>"false", "id"=>"67", "content"=>"Answer 1 of Question 2", "correct"=>"1"}}}, "1"=>{"_destroy"=>"false", "id"=>"42", "content"=>"Question 1", "answers_attributes"=>{"0"=>{"_destroy"=>"false", "id"=>"68", "content"=>"Answer 2 of Question 1", "correct"=>"0"}, "1"=>{"_destroy"=>"false", "id"=>"69", "content"=>"Answer 1 of Question 1", "correct"=>"1"}}}, "1376575795482"=>{"_destroy"=>"false", "content"=>"Question 3", "answers_attributes"=>{"1376575802879"=>{"_destroy"=>"false", "content"=>"Answer 1 of Question 3", "correct"=>"0"}}}}}, "commit"=>"Update Survey", "utf8"=>"✓", "authenticity_token"=>"/vNuB5Ck3QM5p+5ksL3tlmb+ti5nTA/qS96+vbPQkNw="}
这没关系。但由于show.html.erb中的form_tag,show page包含另一个输入表单。
<%= form_tag({:controller => "surveys", :action => "grading"}) do %>
在show.html.erb中再次提交之后我想重定向到results.html.erb并获得正确的结果。但是有这样的错误。
Started POST "/surveys/grading" for 110.174.136.30 at Thu Aug 15 23:19:52 +0900 2013
Processing by SurveysController#grading as HTML
Parameters: {"utf8"=>"✓", "#<Answer:0x7fafd8c5f5a0>"=>"1", "#<Answer:0x7fafd95704a0>"=>"0", "#<Answer:0x7fafd9116a58>"=>"1", "authenticity_token"=>"/vNuB5Ck3QM5p+5ksL3tlmb+ti5nTA/qS96+vbPQkNw=", "#<Answer:0x7fafd8d03a38>"=>"0", "commit"=>"Submit", "#<Answer:0x7fafd8cfc580>"=>"1"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 12 LIMIT 1
Completed 404 Not Found in 3ms
ActionController::RoutingError (No route matches {:action=>"results", :id=>#<Survey id: nil, name: nil, description: nil, attempts: nil, user_id: 12, created_at: nil, updated_at: nil>, :controller=>"surveys"}):
app/controllers/surveys_controller.rb:31:in `grading'
你认为我需要改变回答机制吗?
答案 0 :(得分:1)
尝试这样,你试图在一个数组上调用你的方法。你必须迭代它然后你可以为它分配任何值。您可以对代码进行一些重新分解,以避免循环。
在评分方法中,请执行以下操作:
def grading
@survey = Survey.new
@survey.user_id = current_user.id
@survey.questions.each do |question|
question.auto_check
end
redirect_to results_surveys_path(@survey)
end
在你的问题模型中写一个方法auto_check,如下所示:
def auto_check
answers.each do |answer|
is_correct = true if answer.user_answer and answer.correct
self.save!
end
end
我认为这是一种更好的方法。谢谢。
更新的答案:
每当你尝试在你的路径中传递一个id,这意味着它是一个成员函数,如果你在你的路由中定义集合,那意味着你不能传递一个id(当你路由输出显示时。有一个敏锐的了解更多)。像这样改变你的路线:
resources :surveys do
member do
get 'results'
end
end
现在您可以像这样访问您的网址:
results_survey_path(@survey)
并在您的results
方法中:
def results
@survey = Survey.where(params[:id])
end
希望,现在它会起作用。