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

时间:2016-02-05 13:45:26

标签: ruby-on-rails associations nested-forms nested-resources

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

游戏

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的嵌套资源。通常,我会一次在Workout上创建Player条记录。我还会使用gem nested_fields_forMeasurable添加到Workout,但这样我就可以一次为一个玩家添加/删除一个可衡量的内容。我正在尝试为用户构建一个表单,为每个参与游戏的玩家编辑多个可衡量的数据。

示例表格

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]

到目前为止,我已在edit_measurables.rb的观看/游戏目录下创建了一个视图,并在games_controller中创建了一个名为#edit_measurables的操作。我打算在这里创建___find与Workout对应的Game并构建上面显示的表单。虽然我不知道从哪里开始。我认为我的模型和协会组织不正确。

更新

我已经设法进一步发展,但我仍然遇到了一些问题,尽管有些问题超出了这个问题的范围。

我想构建的表单我试图以下列方式处理...

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

1 个答案:

答案 0 :(得分:1)

<% 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提供measurables一组workout,其中game有一个?{/ p>

此处的问题是您未将measurablesgame&amp; player,特别是通过participations。我想这就是你看到问题的原因;您的measurables必须从其他不相关的表中提取。

如果是这种情况,为什么不将可衡量因素放在participation模型中?

&#34; has_one&#34;锻炼意味着只有一次锻炼...这意味着游戏可以belong_to锻炼?如果是这种情况,那么参与游戏的人就可以在他们的Participation模型中存储 游戏的可衡量数据......

-

#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