使用has_one关联进行预先加载

时间:2012-08-22 14:37:30

标签: activerecord ruby-on-rails-3.1 ruby-on-rails-3.2

我有两个模型,如下面的问题和选择

class Question < ActiveRecord::Base

  has_many :choices, :dependent => :destroy
  accepts_nested_attributes_for :choices, :allow_destroy => true
end

class Choice < ActiveRecord::Base
  attr_accessible :text
  belongs_to :question
end

这里每个问题有3个或更多选项,其中3个是正确的,它存储在问题表的答案栏中。即question.answer

问题:当我显示所有问题时,我想显示选择文字,这意味着正确答案(即)@choice Choice.find(@question.answer)它会显示@choice.text,但会导致{{} 1}}问题。

我们可以实现这个是一个查询或急切加载,如...?

查看:

n+1

1 个答案:

答案 0 :(得分:1)

急切加载会在n+1情况下立即收集所有必需的数据

这些将运行两个查询

  1. 查找所有问题

  2. 在一个查询中为所有问题提出问题的所有选项并将其缓存

  3. 您可以通过

    访问每个问题的选项
    @question.each do |question|
     choices = question.choices
     correct_choice = choices.detect{|choice| choice.id = question.answer}  
    end
    

    并通过

    找到答案的选择
    // return the choice with id @question.answer
    

    关于预先加载的更多细节

    http://railscasts.com/episodes/22-eager-loading

    http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

    示例如何使用

    控制器:

    @questions = Question.all(:include=>:choices)
    

    问题模型:

    def correct_answer
       choices.detect{|choice| choice.id = self.answer}  
    end
    

    查看:(对不起,我对haml并不擅长,如果有什么不对的话,从未尝试过多少纠正)

    %table
      %tr
        %th No
        %th Question  
        %th Answer
      - @questions.each_with_index do |question,index|
        %tr
          %td= index+1
          %td= question.text
          %td= question.correct_answer.text