Game
,Genre
和GameGenre
。游戏通过GameGenres有很多类型,类型通过GameGenres有许多游戏。
我有games/new
表格可以创建新的游戏记录。在这个表单中,我添加了一个fields_for :game_genres
部分,该部分允许用户将game_genre关系记录添加到他们创建的新游戏记录中。
我认为我非常接近这个工作。目前,在提交时它返回错误:“游戏类型游戏不能为空。”我认为这意味着表单连接到game_genres表。我不确定为什么控制器没有提交:game_id值。
这是我的代码。
new.html.erb
<%= form_for(@game) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="form-group">
<%= f.label :title_en, "Game title (English)" %>
<%= f.text_field :title_en, class: 'form-control',
placeholder: "E.g. Marble Madness" %>
</div>
<div class="form-group">
<%= f.label :year, "Year" %>
<%= f.select :year, options_for_select((1950..2017).reverse_each),
{},
{:class => 'form-control'} %>
</div>
<div class="form-group">
<%= f.label :description_en, "Summary" %>
<%= f.text_area :description_en, class: 'form-control' %>
</div>
<hr />
<div class="form-group">
<%= f.fields_for :game_genres do |gf| %>
<%= gf.label :genre_id, "Select a genre" %>
<%= gf.collection_select(:genre_id, Genre.all, :id, :name,
{},
{:class => "form-control"}) %>
<% end %>
</div>
<%= f.submit "Save", class: "btn btn-primary center-block" %>
<% end %>
games_controller.rb (摘录)
def new
@game = current_user.games.build
@game.game_genres.build
end
def create
@game = current_user.games.build(game_params)
if @game.save
flash[:success] = "Game saved: #{@game.title_en} (#{@game.year})"
redirect_to game_path(@game.id)
else
render 'new'
end
end
private
def game_params
params.require(:game).permit(:title_en, :year, :description_en,
game_genres_attributes: [:genre_id])
game.rb
class Game < ActiveRecord::Base
belongs_to :user
has_many :game_genres, foreign_key: :game_id,
dependent: :destroy
has_many :genres, through: :game_genres
accepts_nested_attributes_for :game_genres,
allow_destroy: true
genre.rb
class Genre < ActiveRecord::Base
belongs_to :user
has_many :game_genres, foreign_key: :genre_id,
dependent: :destroy
has_many :games, through: :game_genres
game_genre.rb
class GameGenre < ActiveRecord::Base
belongs_to :game, inverse_of: :game_genres
belongs_to :genre, inverse_of: :game_genres
据我了解,我不需要将game_genres的资源添加到routes.rb。
当我尝试提交新的游戏记录时,这是rails开发服务器的输出:
Started POST "/games" for ::1 at 2015-06-30 18:59:24 +0100
Processing by GamesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"cUbIu3i9niI0R8b9E3KZeYEbNpx8NDj9Jx1MeGvylYDKQj54d3BwSdLsMiPsRBoUTzoTEuMGTk5/KTKAXH7DMA==", "game"=>{"title_en"=>"fdsdcdc", "year"=>"2017", "description_en"=>"dsdc", "game_genres_attributes"=>{"0"=>{"genre_id"=>"8"}}}, "commit"=>"Save"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
(0.1ms) BEGIN
Genre Load (0.3ms) SELECT "genres".* FROM "genres" WHERE "genres"."id" = $1 ORDER BY "genres"."name" ASC LIMIT 1 [["id", 8]]
(0.1ms) ROLLBACK
Rendered shared/_error_messages.html.erb (0.6ms)
Genre Load (0.3ms) SELECT "genres".* FROM "genres" ORDER BY "genres"."name" ASC
据我了解,game_genres_attributes
已正确嵌套并允许。为什么不识别和保存game_id?
非常感谢能够提供帮助的任何人。
修改
我通过从GameGenre模型中删除此验证来使表单正常工作:
validates :game_id, presence: true
我想要这条线,所以我现在想知道如何解决它?
编辑2:
我想这是答案(来自http://makandracards.com/makandra/1346-popular-mistakes-when-using-nested-forms):
嵌套记录正在验证其嵌套父级的存在 记录的外键。如果执行此操作,则无法创建新父级 与新的儿童记录一起记录并需要保存 父母可以保存孩子。你可以选择只显示 父节点之前保存的嵌套子表单,或者只是让它 进行验证。