ruby-on-rails - 向 has_and_belongs_to_many 关系添加多条记录
问题描述
我有一个 HABTM 关系设置如下:
class Game < ApplicationRecord
has_and_belongs_to_many :players
end
和
class Player < ApplicationRecord
validates :name, presence: true, uniqueness: true
has_and_belongs_to_many :games
end
创建新游戏时,我希望用户能够选择现有玩家添加到游戏中。在 Games#new 视图中,我有:
<%= form_with(model: game) do |f| %>
<h3>Select players participating in this game</h3>
<% @players.each do |player| %>
<div class="field">
<%= check_box_tag :player_ids, player.id, false, { id: "player_#{player.id}"} %>
<%= label_tag "player_#{player.id}", player.name %>
</div>
<% end %>
<div class="actions">
<%= f.submit 'Start Game' %>
</div>
<% end %>
This displays each user with a checkbox to select, but when multiple players are selected and a game is created, only the last player is associated with the game.
在控制器中我有
def new
@game = Game.new
@players = Player.all.sort_by &:name
end
def create
@game = Game.new(game_params)
respond_to do |format|
if @game.save
format.html { redirect_to @game }
format.json { render :show, status: :created, location: @game }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @game.errors, status: :unprocessable_entity }
end
end
end
private
def set_game
@game = Game.find(params[:id])
end
def game_params
params.permit(:player_ids)
end
我知道我应该附加 player_ids 但我不确定如何。
解决方案
在表单中使用集合助手:
<%= form_with(model: game) do |f| %>
<h3>Select players participating in this game</h3>
<div class="field">
<%= f.collection_check_boxes(:player_ids, @players, :id, :name) %>
</div>
<div class="actions">
<%= f.submit 'Start Game' %>
</div>
<% end %>
然后在你的强参数中,你需要允许一个标量值数组:
class PlayersController
def new
@game = Game.new
# Sort the records in the DB, not in Ruby land.
@players = Player.all.order(:name)
end
def create
@game = Game.new(game_params)
respond_to do |format|
if @game.save
format.html { redirect_to @game }
format.json { render :show, status: :created, location: @game }
else
format.html do
# required to render the form
@players = Player.all.order(:name)
render :new, status: :unprocessable_entity
end
format.json { render json: @game.errors, status: :unprocessable_entity }
end
end
end
private
def set_game
@game = Game.find(params[:id])
end
def game_params
params.require(:game)
.permit(player_ids: [])
end
end
推荐阅读
- python - 如何在python中查找和删除无效/无意义的文本?
- google-apps-script - 如何只允许在 Google 表格中选中一个复选框
- python - 在 Django 中扩展 `Field` 类
- c# - 反射顺序是确定性的吗?
- python - 在matplotlib中使用.subplot时如何添加标题、x轴标签和y轴标签?
- office-js - Word 启动时自动加载 Office Word WebAddin
- javascript - 如何将 KonvaJs 舞台的使用区域作为高度/宽度属性传递给 toImage 函数?
- twitter - Twitter bot 使用了错误的帐户
- django - 如何更新/删除 Django 中的内容?
- python - 从 csv 文件中绘制许多列