我正在使用茧宝石构建一个创建锦标赛的表单。锦标赛has_many
游戏。Cocoon 让我可以动态地将更多游戏添加到表单中。
当我打电话时@tournament.save
,它会产生以下错误:
Games team one must exist
Games team two must exist
锦标赛.rb
class Tournament < ApplicationRecord
has_many :games
accepts_nested_attributes_for :games, allow_destroy: true
end
游戏.rb
class Game < ApplicationRecord
belongs_to :tournament, optional: false
belongs_to :team_one, polymorphic: true
belongs_to :team_two, polymorphic: true
belongs_to :field, optional: true
end
架构.rb
ActiveRecord::Schema.define(version: 2019_12_24_011346) do
...
create_table "club_teams", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "fields", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "games", force: :cascade do |t|
t.bigint "tournament_id", null: false
t.string "team_one_type", null: false
t.bigint "team_one_id", null: false
t.string "team_two_type", null: false
t.bigint "team_two_id", null: false
t.bigint "field_id", null: false
t.date "date"
t.datetime "start_time"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["field_id"], name: "index_games_on_field_id"
t.index ["team_one_type", "team_one_id"], name: "index_games_on_team_one_type_and_team_one_id"
t.index ["team_two_type", "team_two_id"], name: "index_games_on_team_two_type_and_team_two_id"
t.index ["tournament_id"], name: "index_games_on_tournament_id"
end
create_table "high_school_teams", force: :cascade do |t|
t.string "school_name"
t.string "team_name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "tournaments", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
add_foreign_key "games", "fields"
add_foreign_key "games", "tournaments"
end
锦标赛控制器.rb
class TournamentsController < ApplicationController
...
def create
@tournament = Tournament.new(tournament_params)
if @tournament.save
redirect_to @tournament
else
render 'new'
end
end
private
def tournament_params
params
.require(:tournament)
.permit(:name, games_attributes: [:id, :_destroy, :team_one_id, :team_two_id, :field_id, :date, :start_time])
end
end
在锦标赛控制器中请求参数#create
{
"authenticity_token"=>"iB4JefT9jRdiOFKok38OtjzMwd6Dv3hlHP/QZRtlFgMuVZfbn9PFD7Lebc1DuvfL6/IatDpS5CiubTci5MsCFg==",
"tournament"=>{
"name"=>"foo",
"games_attributes"=>{
"1577935885397"=>{
"team_one_id"=>"high-school-team-2",
"team_two_id"=>"club-team-2",
"date"=>"",
"start_time"=>"",
"_destroy"=>"false"
}
}
},
"commit"=>"Create Tournament"
}
锦标赛控制器中的锦标赛参数#create
<ActionController::Parameters {
"name"=>"foo",
"games_attributes"=><ActionController::Parameters {
"1577937916236"=><ActionController::Parameters {
"_destroy"=>"false",
"team_one_id"=>"high-school-team-2",
"team_two_id"=>"club-team-2",
"date"=>"",
"start_time"=>""
} permitted: true>
} permitted: true>
} permitted: true>
在我看来,accepts_nested_attributes 文档在一对多下所期望的tournament_params
匹配,所以我不明白为什么会出现错误。
关联集合的嵌套属性也可以以散列散列而不是散列数组的形式传递:
Member.create(
name: 'joe',
posts_attributes: {
first: { title: 'Foo' },
second: { title: 'Bar' }
}
)
具有相同的效果
Member.create(
name: 'joe',
posts_attributes: [
{ title: 'Foo' },
{ title: 'Bar' }
]
)
编辑:
锦标赛/new.html.erb
<h1>Create a tournament</h1>
<%= render 'form' %>
<%= link_to 'Back', tournaments_path %>
锦标赛/_form.html.erb
<%= form_with model: @tournament, class: 'tournament-form' do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<section class="games">
<%= f.fields_for :games do |game| %>
<%= render 'game_fields', f: game %>
<% end %>
<hr>
<p>
<%= link_to_add_association "Add game", f, :games,
data: {
association_insertion_node: '.games',
association_insertion_method: :prepend
}
%>
</p>
</section>
<p>
<%= f.submit %>
</p>
<% end %>
锦标赛/_game_fields.html.erb
<section class="nested-fields">
<hr>
<p><strong>Game</strong></p>
<%= render "games/form_fields", f: f %>
<p><%= link_to_remove_association "Remove game", f %></p>
</section>
游戏/_form_fields.html.erb
<section>
<% if HighSchoolTeam.all.count + ClubTeam.all.count < 2 %>
<p>You neeed at least two teams to create a game. Create more high school and/or club teams first.</p>
<% else %>
<section class="game-form">
<p>
<%= f.label :team_one %><br>
<%= f.select :team_one_id, nil, {}, class: "team-one-dropdown" do %>
<optgroup label="High School Teams">
<% HighSchoolTeam.all.each do |high_school_team| %>
<option value="high-school-team-<%= high_school_team.id %>"><%= high_school_team.school_name %></option>
<% end %>
</optgroup>
<optgroup label="Club Teams">
<% ClubTeam.all.each do |club_team| %>
<option value="club-team-<%= club_team.id %>"><%= club_team.name %></option>
<% end %>
</optgroup>
<% end %>
</p>
<p>
<%= f.label :team_two %><br>
<%= f.select :team_two_id, nil, {}, class: "team-two-dropdown" do %>
<optgroup label="High School Teams">
<% HighSchoolTeam.all.each do |high_school_team| %>
<option value="high-school-team-<%= high_school_team.id %>"><%= high_school_team.school_name %></option>
<% end %>
</optgroup>
<optgroup label="Club Teams">
<% ClubTeam.all.each do |club_team| %>
<option value="club-team-<%= club_team.id %>"><%= club_team.name %></option>
<% end %>
</optgroup>
<% end %>
</p>
<p>
<%= f.label :field %><br>
<%= f.collection_select(:field_id, Field.all, :id, :name) %>
</p>
<p>
<%= f.label :date %><br>
<%= f.date_field :date %>
</p>
<p>
<%= f.label :start_time %><br>
<%= f.time_field :start_time %>
</p>
</section>
<% end %>
</section>