如何设置静态表单以在 Rails 中添加关联记录?

How can I set up a static form for adding associated records in Rails?

我正在使用以下型号...

游戏

class Game < ActiveRecord::Base

  has_many :workout
  has_many :participations

end

参与

class Participation < ActiveRecord::Base

  belongs_to :player
  belongs_to :game

end

锻炼

class Workout < ActiveRecord::Base

  belongs_to :player
  belongs_to :game
  has_many   :measurables

end

可测量

class Measurable < ActiveRecord::Base

  belongs_to :workout

end

Workout 当前是 Player 的嵌套资源。通常,我会在 Player 上一次创建一个 Workout 记录。我还会使用 gem nested_fields_forMeasurable 添加到 Workout 中,但这将允许我一次 add/remove 只有一个可测量的,对于一个玩家一次。我现在正在尝试为用户构建一个表单,以便为参与游戏的每个玩家编辑多个可衡量指标。

示例表格

Player            |    Height   |    Weight    |   Hand Span  |
Player 1's Name     [input box]   [input box]     [input box]
Player 2's Name     [input box]   [input box]     [input box]
Player 3's Name     [input box]   [input box]     [input box]
Player 4's Name     [input box]   [input box]     [input box]

到目前为止,我已经在我的 views/games 目录下为 edit_measurables.rb 创建了一个视图,并在 games_controller 中创建了一个名为 #edit_measurables 的操作。我打算在这里 create_or_find 对应 GameWorkout 并构建如上所示的表单。虽然我不确定从这里去哪里。这让我觉得我的模型和关联组织不正确。

更新:

我已经取得了一些进展,但我仍然 运行 遇到一些问题,尽管有些超出了这个问题的范围。

我想要构造的表单我正在尝试以下列方式处理...

<table>
  <thead>
    <tr>
      <th>Player</th>
      <th>Height</th>
      <th>Weight</th>
      <th>Hand</th>
    </tr>
  </thead>
  <tbody>
    <% @game.participations.each do |participant| %>
      <% player = participant.player %>

      <% simple_form_for participant.player do |player_form| %>
        <% workout = Workout.find_or_create_by(...) %>
        <% @measurables.each {|m| workout.measurables.build(...) unless workout.measurables.any? { ... } } %>

      <tr>
        <td><%= player.full_name %></td>

        <% player_form.nested_fields_for :measurables, workout.measurables, wrapper_tag: :td do |measurable_form| %>
          <td><%= measurable_form.input :value, label: false %></td>
        <% end %>
      </tr>
    <% end %>
  </tbody>
</table>
<% game.participations.each do |participation| %>
  <% workout = participation.game.workout %>
  <%= form_for participation.player do |player_form| %>
    <%= fields_for player.measureables.where(workout: workout) do |measurable_form| %>
      <%= measurable_form.text_field :height %>
    <% end %>
  <% end %>
<% end %>

所以你正在做的是给 player 每个 workout 一组 measurables,其中 game 有一个?

这里的 问题 是您没有将 measurables 关联到您的 gameplayer,尤其是通过 participations.我认为这就是您看到问题的原因;你的 measurables 必须从另一个不相关的 table.

中提取出来

如果是这样,为什么不将可测量值放入 participation 模型中?

"has_one" 训练意味着游戏只有一次训练...这意味着游戏可以 belong_to 一次训练??如果是这样的话,参与游戏的人将能够在他们的 Participation 模型中存储 that 游戏的可测量值...

--

#app/views/games/edit.html.erb
<%= form_for @game do |f| %>
    <%= f.fields_for :participations do |p| %>
       <%= p.object.player.name unless p.object.new_record? %>
       <%= p.collection_select :player_id, Player.all, :id, :name if p.object.new_record? %>
       <%= p.number_field :measurable_height %>
       <%= p.number_field :measurable_weight %>
       <%= p.number_field :measurable_hand_span %>
    <% end %>
    <%= f.submit %>
<% end %>

这将允许您直接关联 measurables

#app/models/game.rb
class Game < ActiveRecord::Base
   belongs_to :workout
   has_many   :participations
   has_many   :players, through: :participations
end

#app/models/participation.rb
class Participation < ActiveRecord::Base
   #id | player_id | game_id | measurable_height | measurable_weight | measurable_hand_span | created_at | updated_at
   belongs_to :player
   belongs_to :game
end

使用以下控制器:

#app/controllers/games_controller.rb
class GamesController < ApplicationController

   def new
     @game = Game.new
     @game.participations.build #-> this would be needed to "add" extra fields
   end

   def edit
     @game = Game.find params[:id]
   end

   def update
     @game = Game.find params[:id]
     @game.update update_params
   end

   private

   def update_params
     params.require(:game).permit(partipations_attributes: [:measurable_height, :measurable_weight, :measurable_hand_span])
   end
end