【问题标题】:Add multiple records to has_and_belongs_to_many relationship向 has_and_belongs_to_many 关系添加多条记录
【发布时间】:2021-08-14 00:39:39
【问题描述】:

我的 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,但我不确定如何。

【问题讨论】:

    标签: ruby-on-rails associations relationship rails-activerecord


    【解决方案1】:

    在表单中使用集合助手:

    <%= 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
    

    【讨论】:

    • 谢谢!这成功了,在视图文件中也更干净了?。我确实必须在强参数中要求游戏,否则它们会被过滤掉。 params.require(:game).permit(player_ids: [])
    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多