rails 深度嵌套 form_for 无法保存两次
rails deeply nested form_for not able to save twice
我有一个表格,团队可以在其中注册参加锦标赛。当我第一次保存表格时,表格会按预期保存和路由,但是如果我 return 到 root_path 并重复注册团队的过程,表格根本不会保存(单击"Submit" 按钮什么都不做)。
我的感觉是原始存档中有一些东西在阻止新存档的发生,但我无法确定它是什么。代码如下,希望足够了。
(routes.rb)
root 'tournaments#index'
resources :tournaments do
resources :teams do
resources :players, :only => [:new, :create]
end
end
(型号)
class Tournament < ApplicationRecord
has_many :teams
has_many :players, :through => :teams
accepts_nested_attributes_for :teams
accepts_nested_attributes_for :players
end
class Team < ApplicationRecord
belongs_to :tournament, required: false
has_many :players
accepts_nested_attributes_for :players
end
class Player < ApplicationRecord
belongs_to :team, required: false
has_one :tournament, :through => :team
end
(tournaments_controller.rb)
def index
@tournaments = Tournament.all
end
def show
@tournament = Tournament.find(params[:id])
end
def new
@tournament = Tournament.new
end
def create
@tournament = Tournament.new(tournament_params)
if @tournament.save
flash[:notice] = "#{@tournament.name} saved."
redirect_to root_path
else
render :new
end
end
private
def tournament_params
params.require(:tournament).permit(:name, :deadline, :divisions, :info, :payment, :tournament_date, team_attributes: [:name, :division, :contact_email, :contact_name])
end
(teams_controller.rb)
def create
@team = Team.new(team_params)
if @team.save
flash[:notice] = "Team Registered."
redirect_to tournament_team_path(params[:tournament_id], @team.id)
else
redirect_to new_tournament_team_path(params[:tournament_id])
end
end
def new
@tournament = Tournament.find_by_id(params[:tournament_id])
@team = Team.new
8.times do
@team.players.build
end
end
def show
@tournament = Tournament.find(params[:tournament_id])
@team = Team.find(params[:id])
end
private
def team_params
params.require(:team).permit(:name, :tournament_id, :division, :contact_name, :contact_email, players_attributes: [ :name, :gender, :referee ])
end
从锦标赛#show page to the teams#new action 中输入 link(这个有效...只要它 links 到正确的页面)
<%= link_to(new_tournament_team_path(params[:id])) do %><div class="rounded_btn"><h3>Register Team</h3></div><% end %>
(teams/new.html.erb) - 这种形式不起作用。我应该使用 partials,但我想让它开始工作。
<main class="long_page">
<h1 class="tournament_name"><%= @tournament.name %></h1>
<h3 class="tournament_name">Team Registration</h3>
<section style="align-items: baseline;">
<div class="rounded_box">
<%= form_for [@tournament, @team] do |f| %>
<%= f.hidden_field :tournament_id, :value => @tournament.id %>
<div>
<p>
<%= f.label :division, "Division: " %>
<%= f.select :division, options_for_select([["Mixed", "mixed"], ["Mens", "mens"]]) %>
</p>
<p>
<%= f.text_field :name, required: '' %>
<label alt='Team Name' placeholder='Team Name'></label>
</p>
<p>
<%= f.text_field :contact_name, required: '' %>
<label alt='Contact Person' placeholder='Contact Person'></label>
</p>
<p>
<%= f.text_field :contact_email, required: '' %>
<label alt='Contact Email' placeholder='Contact Email'></label>
</p>
<div class="clear"></div>
</div>
<%= f.fields_for :players do |builder| %>
<div>
<%= builder.text_field :name, required: '' %>
<%= builder.select :gender, options_for_select([["Male", "male"], ["Female", "female"]]) %>
<%= builder.select :referee, options_for_select([["No", "no"], ["Yes", "yes"]]) %>
</div>
<% end %>
</div>
<div class="btn_holder">
<p>
<%= f.submit 'Submit Team', :class => 'rounded_btn' %>
</p></div>
<% end %>
</div>
</section>
这会生成以下 HTML 输出:
<body>
<container>
<header class="header" id="header">
<a href="/"><img alt="Taipei Touch Association Logo" src="/assets/taipei_touch_logo_faded-4bbdd185e462f4d8af3b2d25f221f27f4ae479c8adfa4701b8c3f03e9e31b36c.svg"></a>
<span class="header_span">
<h4>Taipei Touch Association</h4>
<h3>Tournament Management System</h3>
</span>
</header>
<main class="long_page">
<h1 class="tournament_name">Dummy Tournament</h1>
<h3 class="tournament_name">Team Registration</h3>
<section style="align-items: baseline;">
<div class="rounded_box">
<form class="new_team" id="new_team" action="/tournaments/1/teams" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="+CtsL2QcMjj1703iGPpwgs8vYu7TWJfWt9jTUgCYTMaFE9JdvYIMJqdb87z4vKuDzUgb8RO96Mdvk5fW/uJUSw==">
<input value="1" type="hidden" name="team[tournament_id]" id="team_tournament_id">
<div>
<p>
<label for="team_division">Division: </label>
<select name="team[division]" id="team_division"><option value="mixed">Mixed</option>
<option value="mens">Mens</option></select>
</p>
<p>
<input required="required" type="text" name="team[name]" id="team_name">
<label alt="Team Name" placeholder="Team Name"></label>
</p>
<p>
<input required="required" type="text" name="team[contact_name]" id="team_contact_name">
<label alt="Contact Person" placeholder="Contact Person"></label>
</p>
<p>
<input required="required" type="text" name="team[contact_email]" id="team_contact_email">
<label alt="Contact Email" placeholder="Contact Email"></label>
</p>
<div class="clear"></div>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][0][name]" id="team_players_attributes_0_name">
<select name="team[players_attributes][0][gender]" id="team_players_attributes_0_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][0][referee]" id="team_players_attributes_0_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][1][name]" id="team_players_attributes_1_name">
<select name="team[players_attributes][1][gender]" id="team_players_attributes_1_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][1][referee]" id="team_players_attributes_1_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][2][name]" id="team_players_attributes_2_name">
<select name="team[players_attributes][2][gender]" id="team_players_attributes_2_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][2][referee]" id="team_players_attributes_2_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][3][name]" id="team_players_attributes_3_name">
<select name="team[players_attributes][3][gender]" id="team_players_attributes_3_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][3][referee]" id="team_players_attributes_3_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][4][name]" id="team_players_attributes_4_name">
<select name="team[players_attributes][4][gender]" id="team_players_attributes_4_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][4][referee]" id="team_players_attributes_4_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][5][name]" id="team_players_attributes_5_name">
<select name="team[players_attributes][5][gender]" id="team_players_attributes_5_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][5][referee]" id="team_players_attributes_5_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][6][name]" id="team_players_attributes_6_name">
<select name="team[players_attributes][6][gender]" id="team_players_attributes_6_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][6][referee]" id="team_players_attributes_6_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][7][name]" id="team_players_attributes_7_name">
<select name="team[players_attributes][7][gender]" id="team_players_attributes_7_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][7][referee]" id="team_players_attributes_7_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
</form></div>
<div class="btn_holder">
<p>
<input type="submit" name="commit" value="Submit Team" class="rounded_btn" data-disable-with="Submit Team">
</p></div>
</section>
</main>
</container>
</body>
注意:即使使用 nested_forms gem.
,此问题仍然存在
我从 /views/application.erb.html 文件中删除了 <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
,现在该功能似乎可以使用了。
我有一个表格,团队可以在其中注册参加锦标赛。当我第一次保存表格时,表格会按预期保存和路由,但是如果我 return 到 root_path 并重复注册团队的过程,表格根本不会保存(单击"Submit" 按钮什么都不做)。
我的感觉是原始存档中有一些东西在阻止新存档的发生,但我无法确定它是什么。代码如下,希望足够了。
(routes.rb)
root 'tournaments#index'
resources :tournaments do
resources :teams do
resources :players, :only => [:new, :create]
end
end
(型号)
class Tournament < ApplicationRecord
has_many :teams
has_many :players, :through => :teams
accepts_nested_attributes_for :teams
accepts_nested_attributes_for :players
end
class Team < ApplicationRecord
belongs_to :tournament, required: false
has_many :players
accepts_nested_attributes_for :players
end
class Player < ApplicationRecord
belongs_to :team, required: false
has_one :tournament, :through => :team
end
(tournaments_controller.rb)
def index
@tournaments = Tournament.all
end
def show
@tournament = Tournament.find(params[:id])
end
def new
@tournament = Tournament.new
end
def create
@tournament = Tournament.new(tournament_params)
if @tournament.save
flash[:notice] = "#{@tournament.name} saved."
redirect_to root_path
else
render :new
end
end
private
def tournament_params
params.require(:tournament).permit(:name, :deadline, :divisions, :info, :payment, :tournament_date, team_attributes: [:name, :division, :contact_email, :contact_name])
end
(teams_controller.rb)
def create
@team = Team.new(team_params)
if @team.save
flash[:notice] = "Team Registered."
redirect_to tournament_team_path(params[:tournament_id], @team.id)
else
redirect_to new_tournament_team_path(params[:tournament_id])
end
end
def new
@tournament = Tournament.find_by_id(params[:tournament_id])
@team = Team.new
8.times do
@team.players.build
end
end
def show
@tournament = Tournament.find(params[:tournament_id])
@team = Team.find(params[:id])
end
private
def team_params
params.require(:team).permit(:name, :tournament_id, :division, :contact_name, :contact_email, players_attributes: [ :name, :gender, :referee ])
end
从锦标赛#show page to the teams#new action 中输入 link(这个有效...只要它 links 到正确的页面)
<%= link_to(new_tournament_team_path(params[:id])) do %><div class="rounded_btn"><h3>Register Team</h3></div><% end %>
(teams/new.html.erb) - 这种形式不起作用。我应该使用 partials,但我想让它开始工作。
<main class="long_page">
<h1 class="tournament_name"><%= @tournament.name %></h1>
<h3 class="tournament_name">Team Registration</h3>
<section style="align-items: baseline;">
<div class="rounded_box">
<%= form_for [@tournament, @team] do |f| %>
<%= f.hidden_field :tournament_id, :value => @tournament.id %>
<div>
<p>
<%= f.label :division, "Division: " %>
<%= f.select :division, options_for_select([["Mixed", "mixed"], ["Mens", "mens"]]) %>
</p>
<p>
<%= f.text_field :name, required: '' %>
<label alt='Team Name' placeholder='Team Name'></label>
</p>
<p>
<%= f.text_field :contact_name, required: '' %>
<label alt='Contact Person' placeholder='Contact Person'></label>
</p>
<p>
<%= f.text_field :contact_email, required: '' %>
<label alt='Contact Email' placeholder='Contact Email'></label>
</p>
<div class="clear"></div>
</div>
<%= f.fields_for :players do |builder| %>
<div>
<%= builder.text_field :name, required: '' %>
<%= builder.select :gender, options_for_select([["Male", "male"], ["Female", "female"]]) %>
<%= builder.select :referee, options_for_select([["No", "no"], ["Yes", "yes"]]) %>
</div>
<% end %>
</div>
<div class="btn_holder">
<p>
<%= f.submit 'Submit Team', :class => 'rounded_btn' %>
</p></div>
<% end %>
</div>
</section>
这会生成以下 HTML 输出:
<body>
<container>
<header class="header" id="header">
<a href="/"><img alt="Taipei Touch Association Logo" src="/assets/taipei_touch_logo_faded-4bbdd185e462f4d8af3b2d25f221f27f4ae479c8adfa4701b8c3f03e9e31b36c.svg"></a>
<span class="header_span">
<h4>Taipei Touch Association</h4>
<h3>Tournament Management System</h3>
</span>
</header>
<main class="long_page">
<h1 class="tournament_name">Dummy Tournament</h1>
<h3 class="tournament_name">Team Registration</h3>
<section style="align-items: baseline;">
<div class="rounded_box">
<form class="new_team" id="new_team" action="/tournaments/1/teams" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="+CtsL2QcMjj1703iGPpwgs8vYu7TWJfWt9jTUgCYTMaFE9JdvYIMJqdb87z4vKuDzUgb8RO96Mdvk5fW/uJUSw==">
<input value="1" type="hidden" name="team[tournament_id]" id="team_tournament_id">
<div>
<p>
<label for="team_division">Division: </label>
<select name="team[division]" id="team_division"><option value="mixed">Mixed</option>
<option value="mens">Mens</option></select>
</p>
<p>
<input required="required" type="text" name="team[name]" id="team_name">
<label alt="Team Name" placeholder="Team Name"></label>
</p>
<p>
<input required="required" type="text" name="team[contact_name]" id="team_contact_name">
<label alt="Contact Person" placeholder="Contact Person"></label>
</p>
<p>
<input required="required" type="text" name="team[contact_email]" id="team_contact_email">
<label alt="Contact Email" placeholder="Contact Email"></label>
</p>
<div class="clear"></div>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][0][name]" id="team_players_attributes_0_name">
<select name="team[players_attributes][0][gender]" id="team_players_attributes_0_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][0][referee]" id="team_players_attributes_0_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][1][name]" id="team_players_attributes_1_name">
<select name="team[players_attributes][1][gender]" id="team_players_attributes_1_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][1][referee]" id="team_players_attributes_1_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][2][name]" id="team_players_attributes_2_name">
<select name="team[players_attributes][2][gender]" id="team_players_attributes_2_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][2][referee]" id="team_players_attributes_2_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][3][name]" id="team_players_attributes_3_name">
<select name="team[players_attributes][3][gender]" id="team_players_attributes_3_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][3][referee]" id="team_players_attributes_3_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][4][name]" id="team_players_attributes_4_name">
<select name="team[players_attributes][4][gender]" id="team_players_attributes_4_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][4][referee]" id="team_players_attributes_4_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][5][name]" id="team_players_attributes_5_name">
<select name="team[players_attributes][5][gender]" id="team_players_attributes_5_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][5][referee]" id="team_players_attributes_5_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][6][name]" id="team_players_attributes_6_name">
<select name="team[players_attributes][6][gender]" id="team_players_attributes_6_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][6][referee]" id="team_players_attributes_6_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
<div>
<input required="required" type="text" name="team[players_attributes][7][name]" id="team_players_attributes_7_name">
<select name="team[players_attributes][7][gender]" id="team_players_attributes_7_gender"><option value="male">Male</option>
<option value="female">Female</option></select>
<select name="team[players_attributes][7][referee]" id="team_players_attributes_7_referee"><option value="no">No</option>
<option value="yes">Yes</option></select>
</div>
</form></div>
<div class="btn_holder">
<p>
<input type="submit" name="commit" value="Submit Team" class="rounded_btn" data-disable-with="Submit Team">
</p></div>
</section>
</main>
</container>
</body>
注意:即使使用 nested_forms gem.
,此问题仍然存在我从 /views/application.erb.html 文件中删除了 <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
,现在该功能似乎可以使用了。