简单地说,我遇到了一个可怕的2(n)个查询问题。
如果n=数据库中的技能数量,那么我的字符编辑表单将接受2(n)个查询来加载页面。它将选择一个玩家杀死(加入表)每一个技能一次,它将查找每一个技能一次的技能。
这是一些我认为与情况有关的代码。本质上,这个过程中涉及的模型、视图和控制器,更少的模型验证,更少的我不关心的操作。
控制器:
# GET /characters/1/edit
def edit
@character = Character.find(params[:id], :include => {:player_skills => :skill})
stub_player_skills
end
private
def stub_player_skills
@skills = Skill.find(:all)
@skills.each do |skill|
if (skill.player_skills.empty?)
ps = @character.player_skills.build(:skill_id => skill.id, :name => skill.name)
end
end
end
模型:
class Character < ActiveRecord::Base
belongs_to :user
belongs_to :campaign
has_many :sheets, :dependent => :destroy
has_many :tokens, :dependent => :destroy
has_many :player_skills, :dependent => :destroy
has_many :skills, :through => :player_skills
accepts_nested_attributes_for :player_skills, :allow_destroy => true
end
冒犯的观点(haml):
%h1
Editing Character
- form_for @character do |f|
= f.error_messages
%p
= f.label :name
%br
= f.text_field :name
%p
= f.label :race
%br
= f.text_field :race
%p
= f.label :char_class
%br
= f.text_field :char_class
%p
-f.fields_for :player_skills do |ps|
=ps.object.skill.name
=ps.text_field :level
=ps.hidden_field :skill_id
-unless ps.object.new_record?
=ps.check_box '_destroy'
=ps.label '_destroy', 'Remove'
%br
%p
= f.submit
我对这种情况的理解是,存在一个急切的加载,以便在(大致)一个额外的查询中获取关联。
我需要在两个方面适当地应用热切的装载,我只是在如何做它的迷茫。
在stub-player-skills方法中,它需要创建一个playerskill对象
假设角色还没有角色。
它可以从这里的热切加载中获益,因为它循环访问数据库中的每一项技能。这是第一个“n查询”的来源。
然后在视图中,字段“for”循环遍历我们收集的所有玩家技能,因为在这里不可能急于加载,当我调用=ps.object.skill.name打印出技能的名称时,它执行一个技能查找,这将引入第二组“n-queries”。
我主要关心的是视图层,我找不到任何文档(rails api或其他文档),说明如果您使用fields\for生成嵌套表单,那么您如何能够急于加载关联。
感谢您的所有回复:)
~罗比