2016-06-21 5 views
0

Исследование имеет много вопросов, на которые есть ответы на многие вопросы:Неопределенный метод викторины модели

class Survey < ActiveRecord::Base 
    has_many :questions, :dependent => :destroy 
    accepts_nested_attributes_for :questions, :reject_if => -> (a) {a[:content].blank? }, :allow_destroy => true 
end 

class Question < ActiveRecord::Base 
    belongs_to :survey 
    has_many :answers, :dependent => :destroy 
    accepts_nested_attributes_for :answers, :reject_if => -> (a) {a[:content].blank? }, :allow_destroy => true 
end 

class Answer < ActiveRecord::Base 
    belongs_to :question 
end 

в SurveysController, я делаю это:

def show 
    @survey = Survey.find(params[:id]) 
    @questions = @survey.questions 
    @answers = @questions.answers 
    end 

и я получаю сообщение об ошибке:

undefined method `answers' for #<Question::ActiveRecord_Associations_CollectionProxy:0x007f7f68af6948> 

и рельсы указывают на эту линию как проблему: @answers = @questions.answers

Почему?

ответ

1

Это потому, что вы пытаетесь загрузить ВСЕ ответы из ВСЕХ вопросов, но вы используете синтаксис, который предназначен для загрузки ВСЕХ ответов из вопроса SINGLE.

Например, это было бы правильно:

@question_1 = @survey.questions.first # Notice the `first` 
@answers = @question_1.answers   # Gets all answers for the `first` question 

Посмотрите, как я получаю один question, а затем получить свои ответы? Это верно.

Теперь, если вы хотите, чтобы получить все ответы на все вопросы, вы выиграли бы от использования collect метода:

@questions = @survey.questions 
@answers = @questions.collect(&:answers) 

Что это collect способ, по существу это будет запускать each цикл по каждому вопросу и " собирает "своих детей (answers) в массив.

-

Менее краткий, хотя и более эффективный подход был бы избежать N + 1 запросы и использовать includes вместо collect

@answers = [] 
@questions.includes(:answers).each do |q| 
    @answers << q.answers 
end 
+0

я получаю сейчас. Спасибо! –

Смежные вопросы