Вкратце, я столкнулся с проблемой проблем 2 (n) запросов. Если n = количество навыков в базе данных, то мои символы # edit form будут принимать 2 (n) запросов для загрузки страницы. Он будет ВЫБРАТЬ PlayerSkill (таблица соединения) после каждого навыка, и он будет искать навык один раз за умение.Возможно ли загружать ассоциации с помощью nested_attributes?
Вот какой-то код, который, я считаю, уместен в этой ситуации. По сути, модели, представления и контроллеры, участвующие в этом процессе, меньше валидности модели и меньше действий, которые меня не волнуют.
Контроллер:
# 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-запросы».
Затем, при просмотре, fields_for проходит через все PlayerSkills, которые мы собрали, потому что здесь нет возможности загружать нагрузку, когда я вызываю = ps.object.skill.name, чтобы распечатать имя умения, это выполняет поиск навыка, который включает второй набор «n-запросов».
Моя основная проблема заключается в уровне представления, я не могу найти никакой документации (Rails API или иначе), в которой говорится, как можно было бы загружать ассоциации, если вы используете поля для создания вложенной формы.
Спасибо за любые ответы :) ~ Робби
Это не совсем работает, потому что мне все равно нужно перебирать все возможные навыки (см. Stub_player_skills) и проверить, существует ли PlayerSkill. Представьте, что у нас есть навык №1, №2 и №3. Если у меня есть навык №1 и №3, тогда нам нужно заглушить №2. Я думаю, проблема в том, что я использую ActiveRecord для выполнения другой «находки», нужно ли вместо этого перебирать массив в моей бизнес-логике? – Robbie
Прошу прощения, я полностью пропустил эту часть. Я вижу, что вы сейчас пытаетесь сделать ... Я пересмотрю свой пост. – Coderama
С небольшими изменениями я получил эту работу, и контроллер больше не требует n-запросов для загрузки PlayerSkills. Тем не менее, просмотр все еще принимает n-запросы, потому что я вызываю вызов ps.object.skill.name; Мне кажется, что это может быть ограничением в том, как Rails обрабатывает поля, хотя это и довольно неудачно. – Robbie