简体   繁体   中英

rails : How can I call methods in the nested model from parents?

This is my model.

Survey

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

Question : there is is_correct(boolean) column which indicates whether students get the right answer or not.

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

Answer : there is correct(boolean) column which teacher checks making the survey(test), and there is user_answer(boolean) column which students mark taking the test.

class Answer < ActviveRecord::Base
  belongs_to :question

I want to compare correct and user_answer in Answer model, and save the answer to is_correct in Question model.

There are not only basic CRUD methods for generating question and answer, but also three extra methods for answering(GET)/grading(POST) examination, showing(GET) results. I can check there are no problem in this routes from the result of rake routes.

Updated Question : I changed my controller and Question model.

Here are methods in survey controller.

def answering
  @survey = Survey.find(params[:id])
end

def grading
  @survey = Survey.find(params[:id])
  @survey.user_id = current_user.id
  @survey.questions.each do |q|
    q.auto_check 
  end 
  redirect_to results_survey_path(@survey)
end

def results
end

Here is question controller.

def auto_check
  answers.each do |a|
    is_correct = true if a.user_answer and a.correct 
    self.save!
  end
end

The result of rake routes.

$ rake routes | grep survey
(in /home/seriousin/ClassCasts)
        answering_survey GET    /surveys/:id/answering(.:format)            surveys#answering
          grading_survey POST   /surveys/:id/grading(.:format)              surveys#grading
          results_survey GET    /surveys/:id/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

* The problem is I can't call survey object saved user input. *

I let the results method empty. Using redirect_to, I don't need to generate another survey object.

  def results
      #@survey = Survey.where(params[:survey_id])
  end

I think it's OK. Because I can pass survey object as a parameter from grading method.

def grading
  @survey = Survey.find(params[:id])
  @survey.user_id = current_user.id
  @survey.questions.each do |q|
    q.auto_check 
  end 
  redirect_to results_survey_path(@survey)
end

But the result is 'undefined method `name' for nil:NilClass'... How can I use object contains user input?

Thanks advanced.

auto_check方法应该在问题模型内部,而不是在问题控制器内部。

Your @survey.questions.each gives you an instance of Question model and you are calling a method defined in the QuestionsController on it. Had the auto_check been a member of Question model you wouldn't have received this error.

If you want to keep auto_check method in the QuestionsController then I think you should pass in the question instance as a parameter like follows:

def auto_check(question)
  question.answers.each do |a|
    is_correct = true if a.user_answer and a.correct 
    ...
  end
end

and update the call as follows:

@survey.questions.each do |q|
  auto_check(q)
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM