Вопрос по ruby-on-rails – В чем разница между использованием «:» и «@» в fields_for

4

Я устанавливаю встроенные формы в моем приложении rails.

Это не работает

<h1>PlayersToTeams#edit</h1>
<%= form_for @players_to_teams do |field| %>
  <%= field.fields_for @players_to_teams.player do |f| %>
    <%= f.label :IsActive %>
    <%= f.text_field :IsActive %>
  <% end %>
  <%= field.label :BT %>
  <%= field.text_field :BT %>
  <br/>
  <%= field.submit "Save", class: 'btn btn-primary' %>
<% end %> 

Дает мнеActiveRecord::AssociationTypeMismatch ошибка. Обратите внимание на@players_to_teams.player вforms_for линия.

Это работает:

<h1>PlayersToTeams#edit</h1>
<%= form_for @players_to_teams do |field| %>
    <%= field.fields_for :player do |f| %>
        <%= f.label :IsActive %>
        <%= f.text_field :IsActive %>
    <% end %>
    <%= field.label :BT %>
    <%= field.text_field :BT %>
    <br/>
    <%= field.submit "Save", class: 'btn btn-primary' %>
<% end %>

Обратите внимание на:player позвонить вfields_for линия.

В чем разница между использованием символа и экземпляра? Я думаю, я бы хотел использовать экземпляр в этом случае, но я думаю, нет?

Edit

модели:

class Player < ActiveRecord::Base
  has_many :players_to_teams
  has_many :teams, through: :players_to_teams
end

class PlayersToTeam < ActiveRecord::Base
  belongs_to :player
  belongs_to :team

  accepts_nested_attributes_for :player
end

контроллер:

class PlayersToTeamsController < ApplicationController
  def edit
    @players_to_teams=PlayersToTeam.find(params[:id])
  end

  def update
    @players_to_teams=PlayersToTeam.find(params[:id])
    respond_to do |format|
      if @players_to_teams.update_attributes(params[:players_to_team])
        format.html { redirect_to @players_to_teams, notice: 'Player_to_Team was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @players_to_teams.errors, status: :unprocessable_entity }
      end
    end
  end
end

Example Project

Github:https://github.com/workmaster2n/embedded-form-errors

Ваш Ответ

1   ответ
5

Это похоже наfields_for не могу понять, чтоplayer Ассоциация для@players_to_teams переменная экземпляра. Вы обойдете это, явно указав название ассоциации (т.е.:player). Вы определяете ассоциацию в обоих направлениях? т.е .:

class PlayersToTeam < ActiveRecord::Base
  has_one :player
end

class Player < ActiveRecord::Base
  belongs_to :players_to_team
end

Кроме того, глядя надокументация дляfields_forпервый параметр называетсяrecord_nameтак что похоже, что Rails ожидаетname ассоциации, а не самой ассоциации. Но трудно точно сказать, что делает этот метод, не заглядывая в код дальше, и некоторые из их примеров действительно передают ассоциацию непосредственно вfields_for.


Хорошо, я смог клонировать ваш пример проекта и воспроизвести ошибку. Я думаю, что понимаю, что происходит.

После вашего звонкаaccepts_nested_attributes_forТеперь у вас есть метод экземпляра в вашей модели с именемplayer_attributes=, Это в дополнение кplayer= метод, который обычно определяется дляhas_one ассоциация.player_attributes= метод принимает хэш атрибутов, тогда какplayer= метод принимает только фактическийPlayer объект.

Вот пример ввода текста, сгенерированного при вызовеfields_for @players_to_teams.player:

<input name="players_to_team[player][name]" ... />

и здесь тот же самый ввод при вызовеfields_for :player:

<input name="players_to_team[player_attributes][name]" ... />

Когда вы звонитеupdate_attributes в вашем контроллере первый пример будет вызыватьplayer=пока второй пример назовуplayer_attributes=, В обоих случаях аргумент, передаваемый методу, является хешем (потому чтоparams в конечном итоге просто хэш хэшей).

Вот почему вы получаетеAssociationTypeMismatch: вы не можете передать хешplayer=толькоPlayer объект.

Похоже, что единственный безопасный способ использованияfields_for сaccepts_nested_attributes_for путем передачи названия ассоциации, а не самой ассоциации.

Такto answer your original questionразница в том, что один работает, а другой нет :-)

Error: User Rate Limit Exceededthe docs on AssociationTypeMismatchError: User Rate Limit ExceededCommentError: User Rate Limit ExceededPatchError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Tyler DeWitt
Error: User Rate Limit Exceededfields_forError: User Rate Limit Exceededform_forError: User Rate Limit ExceededAssociationTypeMismatchError: User Rate Limit ExceededassigningError: User Rate Limit Exceeded
Error: User Rate Limit Exceededform_forError: User Rate Limit Exceeded Tyler DeWitt
Error: User Rate Limit Exceeded Tyler DeWitt

Похожие вопросы