簡単に言うと、恐ろしい2(n)クエリの問題が発生しました。n =データベース内のスキルの数の場合、私のcharacters#editフォームはページをロードするために2(n)クエリを実行します。スキルごとにPlayerSkill(結合テーブル)を選択し、スキルごとに1回スキルを検索します。
これが状況に関連すると私が信じるいくつかのコードです。本質的に、このプロセスに関係するモデル、ビュー、およびコントローラーは、モデルの検証が少なく、私が気にしないアクションも少なくなります。
コントローラー:
# 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
状況についての私の理解は、(大まかに)単一の追加クエリで関連付けを取得するための積極的な読み込みが存在することです。
2つの領域で積極的な読み込みを適切に適用する必要がありますが、その方法については途方に暮れています。
steb_player_skillsメソッドでは、キャラクターにPlayerSkillオブジェクトがまだないことを前提として、 PlayerSkillオブジェクトを作成する必要があります。 データベース内の各スキルをループするため、ここで積極的に読み込むことでメリットが得られる可能性があります。これが最初の「nクエリ」の出所です。
次に、ビューで、fields_forは、取得したすべてのPlayerSkillをループします。これは、ここで熱心にロードする方法がないため、= ps.object.skill.nameを呼び出してスキルの名前を出力すると、スキルルックアップが実行されます。 、「n-クエリ」の2番目のセットを取り込みます。
私の主な関心事はビューレイヤーにあります。fields_forを使用してネストされたフォームを生成する場合に、関連付けを熱心にロードする方法を説明するドキュメント(Rails APIなど)が見つかりません。
ありとあらゆる回答をありがとう:)〜Robbie