首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎么才能重构这个呢?同时也减少了对服务器的调用?

我怎么才能重构这个呢?同时也减少了对服务器的调用?
EN

Stack Overflow用户
提问于 2017-03-23 12:30:09
回答 5查看 96关注 0票数 0

我有这个方法。它的工作是返回一份已经毕业于开发商的学员名单。用户筛选他们在开发人员中寻找的技能。返回列表时,列表的顶部是更相关的开发人员。

这是控制器方法:

代码语言:javascript
复制
  def filter
    @skills = Skill.all
    @developers = []
    unless params[:ids].nil?
      params[:ids].each do |skill|
        skill = @skills.find(skill)
        skill.trainees.each do |developer|
          @developers << developer
        end
      end
    end
    if @developers.empty?
      @developers = Trainee.developers.all
    else
      @developers = @developers.group_by {|x| x}.map {|k, v| [k, v.count]}
      @developers.sort_by!(&:last).reverse!
      @developers.map! do |developer|
        developer[0]
      end
    end
    respond_to do |format|
      format.js {}
    end
  end

目前,相同的方法正在按我想要的次数访问服务器。下面的服务器日志显示的结果是我单击了11个要过滤的按钮。可以是1、5或20,这取决于用户所寻找的内容。

代码语言:javascript
复制
Processing by SkillsController#filter as */*
  Parameters: {"ids"=>["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]}
  Skill Load (0.6ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 1 LIMIT 1
  Trainee Load (0.6ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 1
  Skill Load (0.4ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 2 LIMIT 1
  Trainee Load (0.6ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 2
  Skill Load (0.3ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 3 LIMIT 1
  Trainee Load (1.3ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 3
  Skill Load (6.1ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 4 LIMIT 1
  Trainee Load (0.6ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 4
  Skill Load (0.3ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 5 LIMIT 1
  Trainee Load (0.9ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 5
  Skill Load (2.6ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 6 LIMIT 1
  Trainee Load (2.0ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 6
  Skill Load (4.2ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 7 LIMIT 1
  Trainee Load (0.9ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 7
  Skill Load (1.2ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 8 LIMIT 1
  Trainee Load (3.0ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 8
  Skill Load (0.3ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 9 LIMIT 1
  Trainee Load (0.8ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 9
  Skill Load (2.1ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 10 LIMIT 1
  Trainee Load (0.6ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 10
  Skill Load (0.3ms)  SELECT  `skills`.* FROM `skills` WHERE `skills`.`id` = 11 LIMIT 1
  Trainee Load (0.8ms)  SELECT `trainees`.* FROM `trainees` INNER JOIN `mastered_skills` ON `trainees`.`id` = `mastered_skills`.`trainee_id` WHERE `mastered_skills`.`skill_id` = 11
  Rendering skills/filter.js.haml
  Skill Load (0.7ms)  SELECT `skills`.* FROM `skills` INNER JOIN `mastered_skills` ON `skills`.`id` = `mastered_skills`.`skill_id` WHERE `mastered_skills`.`trainee_id` = 5
  Skill Load (0.5ms)  SELECT `skills`.* FROM `skills` INNER JOIN `mastered_skills` ON `skills`.`id` = `mastered_skills`.`skill_id` WHERE `mastered_skills`.`trainee_id` = 2728
  Skill Load (0.6ms)  SELECT `skills`.* FROM `skills` INNER JOIN `mastered_skills` ON `skills`.`id` = `mastered_skills`.`skill_id` WHERE `mastered_skills`.`trainee_id` = 10
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-03-24 05:26:53

首先,@skills可以定义为:@skills = params[:ids].nil? ? Skill.all : Skills.where(id: params[:ids])

然后你就面临着n+1问题。为了避免这种情况,您必须使用殷切装载协会 (ELA)或联接。

若要返回带ELA的受训者对象,可以使用mapflatten

接下来,你有一个很好的角色:

代码语言:javascript
复制
@developers = @developers.group_by {|x| x}.map {|k, v| [k, v.count]}
@developers.sort_by!(&:last).reverse!

sort_by(&:last).reverse工作得很快。

本部分:

代码语言:javascript
复制
@developers.map! do |developer|
  developer[0]
end

可改为:

代码语言:javascript
复制
@developers.map(&:first)

并与以前的sort_by联合

代码语言:javascript
复制
@developers = @developers.sort_by(&:last).reverse.map(&:first)

希望能帮上忙。

票数 1
EN

Stack Overflow用户

发布于 2017-03-23 12:40:18

优化本部分:

代码语言:javascript
复制
@skills = Skill.all
@developers = []
unless params[:ids].nil?
  params[:ids].each do |skill|
    skill = @skills.find(skill)
    skill.trainees.each do |developer|
      @developers << developer
    end
  end
end

至:

代码语言:javascript
复制
@developers = Skill.where(id: params[:ids]).joins(:trainees).select('trainees.*')
票数 1
EN

Stack Overflow用户

发布于 2017-03-23 12:38:07

所描述的问题看起来像一个N+1 problem。急切地加载关联可能会有所帮助:Querying.html#急切-加载-关联

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42976117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档