2013-06-19 112 views
1

我刚刚更改了操作中competitors_controller.rb从...这是渴望加载做我认为它应该做什么?

def audit 
    @review = Review.find(params[:review_id]) 
    @competitor = @review.competitors.find(params[:id]) 
    respond_with(@review, @competitor) 
end 

...到...

def audit 
    @review = Review.find(params[:review_id]) 
    @competitor = Competitor.find(params[:id], :include => {:surveys => {:question => [:condition, :precondition]}}) 
    respond_with(@review, @competitor) 
end 

...在页面上被加载超时。

底层的关联是:

class Competitor < ActiveRecord::Base 
    has_many :surveys 
end 

class Survey < ActiveRecord::Base 
    belongs_to :competitor 
    belongs_to :question 
    delegate :dependencies, :precondition, :condition, :to => :question 
end 

class Question < ActiveRecord::Base 
    has_many :dependancies, :class_name => "Question", :foreign_key => "precondition_id" 
    belongs_to :precondition, :class_name => "Question" 
    has_many :surveys, :dependent => :delete_all 
end 

基本上,audit.html.haml页面加载:

@competitor.surveys.{sorting, etc}.each do |s| 
    s.foo, s.bar 
    s.{sorting, etc}.dependant_surveys.each do |s2| 
     s2.foo, s2.bar 
     s2.{sorting, etc}.dependant_surveys.each do |s3| 
      s3.foo, s3.bar, etc etc 

如果我窝太远,页面没有之前加载时间出。

我需要知道的是,我是否已经在competitor_controllers.rb理论上加速了以下两种方法中的每一种,在构建audit.html.haml时经常调用这些方法?

class Survey < ActiveRecord::Base 
    def dependant_surveys 
    self.review.surveys.select{|survey| self.dependencies.include?(survey.question)} 
    end 
end 

class Question < ActiveRecord::Base 
    def dependencies 
    Question.all.select{|question| question.precondition == self} 
    end 
end 

(我说“理论上”,因为我知道这个问题也可以用基准的回答。但在此之前我走到这一步我想检查我的理论正确的。)

回答

1

你在ruby中做了很多处理,而且没有必要这么做。您应将所有操作如

Question.all.select{|question| question.precondition == self} 
@competitor.surveys.{sorting, etc} 

移动到数据库。

如果我理解正确,第一行是为了选择所有具有给定问题前提条件的记录。请记住,Question.all返回一个数组,因此您可以在数组中执行select操作,并且您可以在db中执行该操作,其范围仅为scope :has_precondition, -> {|q| where(precondition_id: q.id}

鉴于您始终以相同方式对模型进行排序,您可以考虑使用order子句创建默认范围。用红宝石做它是非常有效的。

1

的预先加载的外观像它应该工作,但更重要的是,这些是你可以并应该使用SQL来做的事情。加载并遍历数据库中的所有ActiveRecord模型可能会非常耗时(正如您找到的那样),而如何在SQL中实现它将允许您直接从单个查询加载所有模型。这可能需要一段时间才能掌握,但它非常值得!

0

据我所知,你只能加入关联加载。我不认为你有什么将会工作。您没有向我们展示Question.condition的定义,或Survey.review。此外,您正在加载的关联在您执行自己的查询时将不会被您的方法dependent_surveysdependencies使用。

AFAICT您的急切加载不会造成任何差异,或者它可能会减慢速度。我想你必须重构你的dependent_surveys作为一种关联和热切的加载。我没有丝毫的线索知道该方法试图在高层次上做什么,所以我甚至不会试图重构它。

相关问题