Rails 3.1+嵌套表单问题:无法批量分配受保护的属性 [英] Rails 3.1+ Nested Forms Issue: Can't mass-assign protected attributes

查看:88
本文介绍了Rails 3.1+嵌套表单问题:无法批量分配受保护的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个篮球应用程序,其中的名册上有很多球员,并且一个球员可以在多个名册上.(多对多的原因是球员-球员档案)

Roster.rb

class Roster < ActiveRecord::Base
      belongs_to :team
      has_many :rosterizes
      has_many :players, :through => :rosterizes
      accepts_nested_attributes_for :players
      attr_accessible :jersey_number, :team_id, :class_year, :players
    end

Rosterizes.rb (我叫这个名字很糟糕...)

class Rosterize < ActiveRecord::Base
  belongs_to :player
  belongs_to :roster
  attr_accessible :player_id, :roster_id
end

Player.rb

class Player < ActiveRecord::Base
  has_many :rosterizes
  has_many :rosters, :through => :rosterizes
  validates_presence_of :first_name, :last_name
  attr_accessible :first_name, :last_name, :active
end

视图

<div class="well">
    <h2>New Player</h2>
    <%= simple_form_for @roster, :url =>player_added_team_path, :html => { :class => 'form-horizontal' } do |f| %>
        <%= f.simple_fields_for @new_player do |x| %>
            <%= x.input :first_name %>
            <%= x.input :last_name %>
        <%end%>
        <%=f.input :class_year %>       
        <%=f.input :jersey_number %>
        <%=f.input :team_id, :as => :hidden, :input_html => {:value => params[:id]}%>

        <div class="well">
        <%= f.button :submit, :class => 'btn-primary icon-plus-sign btn-success', :value => "Add To Team" %>
        </div>
    <%end%>
</div>

我要发送给控制器的参数:

"roster"=>{"player"=>{"first_name"=>"first name", "last_name"=>"last name"}, "class_year"=>"freshman", "jersey_number"=>"23", "team_id"=>"1"}, "commit"=>"Add To Team", "id"=>"1"}

正在处理保存的控制器:

def player_added
   @team = Team.find(params[:id])

   #where the issue is happening
   @roster = @team.rosters.build(params[:roster])
   @roster.save
   ...

end

我有一个使用参数的方法,但是,我想了解我在这里为将来/学习目的做错了什么,以及为什么它给了我:无法批量分配受保护的属性

我的解决方法(有点怪异):

def player_added

    @team = Team.find(params[:id])
    @roster = @team.rosters.build(:class_year => params[:roster][:class_year], :jersey_number => params[:roster][:jersey_number])
    @new_player = @roster.players.build(:first_name => params[:roster][:player][:first_name], :last_name => params[:roster][:player][:last_name])

    @roster.save
    @new_player.save

    ...

end

我正在使用Simple_Form 2.0 ...

我知道这是很多信息,但在此先感谢您!

解决方案

以防万一其他人遇到与我相同/相似的问题...

我在=> https://github.com/ryanb/nested_form 中安装了此插件>

这就是我所做的更改:

Roster.rb

class Roster < ActiveRecord::Base
  belongs_to :team
  has_many :rosterizes
  has_many :players, :through => :rosterizes
  accepts_nested_attributes_for :players
  attr_accessible :jersey_number, :class_year, :players, :player_attributes
end

我也将视图更改为:

 <%= simple_nested_form_for @roster, :url =>player_added_team_path, :html => { :class => 'form-horizontal' } do |f| %>
      <%= f.simple_fields_for :players, @roster.players.build do |x| %>
           # nested form
           ...
      <%end%>
      # form
      ...
<%end%>

控制器以保存 def player_added

@team = Team.find(params[:id])
@roster = @team.rosters.build(params[:roster])
@roster.save

...

结束

这让我很难理解,希望这可以减少您寻找答案/学习nested_forms的时间!

解决方案

问题在于命名嵌套关联属性的方式以及发送的参数:

嵌套的:players的属性应为:players_attributes,并且不应列出:team_id(因为它会覆盖团队关联的魔力):

attr_accessible :jersey_number, :class_year, :players_attributes

并且参数应具有以下格式:

"roster"=>{"players_attributes"=>[{"first_name"=>"first name", "last_name"=>"last name"}], "class_year"=>"freshman", "jersey_number"=>"23"}, "commit"=>"Add To Team", "id"=>"1"}

要实现此目的,您可能应该将simple_form_for @roster更改为simple_nested_form_for @roster

请注意,您无需在"roster"的参数中包含"team_id"属性,因为您已经在加载花名册并将其与之相关联.

I have a basketball app, where a Roster has many Players, and a Player can be on multiple Rosters.(Reason for many-to-many is for a Player-Roster archive)

Roster.rb

class Roster < ActiveRecord::Base
      belongs_to :team
      has_many :rosterizes
      has_many :players, :through => :rosterizes
      accepts_nested_attributes_for :players
      attr_accessible :jersey_number, :team_id, :class_year, :players
    end

Rosterizes.rb(poorly named I know...)

class Rosterize < ActiveRecord::Base
  belongs_to :player
  belongs_to :roster
  attr_accessible :player_id, :roster_id
end

Player.rb

class Player < ActiveRecord::Base
  has_many :rosterizes
  has_many :rosters, :through => :rosterizes
  validates_presence_of :first_name, :last_name
  attr_accessible :first_name, :last_name, :active
end

The View

<div class="well">
    <h2>New Player</h2>
    <%= simple_form_for @roster, :url =>player_added_team_path, :html => { :class => 'form-horizontal' } do |f| %>
        <%= f.simple_fields_for @new_player do |x| %>
            <%= x.input :first_name %>
            <%= x.input :last_name %>
        <%end%>
        <%=f.input :class_year %>       
        <%=f.input :jersey_number %>
        <%=f.input :team_id, :as => :hidden, :input_html => {:value => params[:id]}%>

        <div class="well">
        <%= f.button :submit, :class => 'btn-primary icon-plus-sign btn-success', :value => "Add To Team" %>
        </div>
    <%end%>
</div>

The paramaters I am sending to the controller:

"roster"=>{"player"=>{"first_name"=>"first name", "last_name"=>"last name"}, "class_year"=>"freshman", "jersey_number"=>"23", "team_id"=>"1"}, "commit"=>"Add To Team", "id"=>"1"}

Controller that is handling the Saving:

def player_added
   @team = Team.find(params[:id])

   #where the issue is happening
   @roster = @team.rosters.build(params[:roster])
   @roster.save
   ...

end

I have a work around using using the parameters, BUT I would like to understand what I am doing wrong here for future/learning purposes and why it is giving me: Can't mass-assign protected attributes

My work around(kinda hacky):

def player_added

    @team = Team.find(params[:id])
    @roster = @team.rosters.build(:class_year => params[:roster][:class_year], :jersey_number => params[:roster][:jersey_number])
    @new_player = @roster.players.build(:first_name => params[:roster][:player][:first_name], :last_name => params[:roster][:player][:last_name])

    @roster.save
    @new_player.save

    ...

end

I am using Simple_Form 2.0...

I know this is a lot of information, but thanks you in advance!

SOLUTION

Just incase anyone else is having same the same/similar issue I am...

I installed this plug in => https://github.com/ryanb/nested_form

So this is the changes I made:

Roster.rb

class Roster < ActiveRecord::Base
  belongs_to :team
  has_many :rosterizes
  has_many :players, :through => :rosterizes
  accepts_nested_attributes_for :players
  attr_accessible :jersey_number, :class_year, :players, :player_attributes
end

I also made the change to the view to:

 <%= simple_nested_form_for @roster, :url =>player_added_team_path, :html => { :class => 'form-horizontal' } do |f| %>
      <%= f.simple_fields_for :players, @roster.players.build do |x| %>
           # nested form
           ...
      <%end%>
      # form
      ...
<%end%>

Controller to save def player_added

@team = Team.find(params[:id])
@roster = @team.rosters.build(params[:roster])
@roster.save

...

end

This was a pain in the butt for me to understand, Hopefully this will cut down the time for any of you looking for answers/learning nested_forms!

解决方案

The problem is with the way you are naming your nested association attribute, and with the parameters you are sending:

The attribute for nested :players should be :players_attributes, and :team_id should not be listed (because that overrides the team association rails magic):

attr_accessible :jersey_number, :class_year, :players_attributes

And the parameters should have this format:

"roster"=>{"players_attributes"=>[{"first_name"=>"first name", "last_name"=>"last name"}], "class_year"=>"freshman", "jersey_number"=>"23"}, "commit"=>"Add To Team", "id"=>"1"}

To accomplish this, you should probably change simple_form_for @roster to simple_nested_form_for @roster

Note that you don't need to include the "team_id" attribute in the parameters for "roster" because that you are already loading and associating the roster to it.

这篇关于Rails 3.1+嵌套表单问题:无法批量分配受保护的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆