用于向form_for添加下拉菜单的按钮

时间:2014-07-28 20:17:51

标签: ruby-on-rails coffeescript

我遇到了一个问题,我无法得到一个好的解决方案,希望有比我更多经验的人可以提供帮助。

我正在创建一个rails应用程序,您可以在游戏中注册匹配项,然后从下拉列表中选择哪些玩家参与该游戏。我这样做是通过使用带有嵌套fields_for的form_for。

<%= form_for [@group, @match] do |f| %>
  <table class="table" id="match_players">
    <tr>
      <th>Placement</th>
      <th>Player</th>
    </tr>
    <%= create_player_in_match_row(f, 1, @group.active_players) %>
    <%= create_player_in_match_row(f, 2, @group.active_players) %>
  </table>
  <a id="add_player_row">Add Player</a>
  <%= f.submit("Create") %>
<% end %>

create_player_in_match_row 方法用于创建带下拉列表的行。代码在一个帮助器类中,它看起来像这样:

def create_player_in_match_row(form, nr, players)
  form.fields_for :player_in_matches, @match.player_in_matches.build do |pim|
    "<tr id='row_p#{ nr }'>
      #{ pim.hidden_field "placement", value: nr }
      <td>#{ nr }.</td>
      <td>#{ player_select_tag(pim, players) }</td>
      <td>#{ tie_check_box(pim) }</td>
    </tr>".html_safe
  end
end

def player_select_tag(pim, players)
  players = players.order "name ASC"
  pim.select :player_id,
             players.map { |p| [p.name, p.id] },
             { include_blank: false },
             { class: 'chosen-select' }
end

问题: 正如您在form_for中看到的,我有一个链接“添加播放器”。我希望这个按钮添加一个带有下拉列表的新行,用于选择玩家。

截至目前,我正在coffeescript中创建一个新行:

$("#add_player_row").click ->
  select_row_original = document.getElementById('row_p1')
  new_select_row = select_row_original.cloneNode(true)
  new_select_row_placement = document.getElementsByClassName('player_row').length + 1

  # Change A LOT of ids and stuff

  $("#match_players").append(new_select_row)

但这感觉很糟糕,而且代码真的不直观。有人能指出我更聪明的解决方案吗?有没有办法可以重用辅助类方法来添加行?

1 个答案:

答案 0 :(得分:1)

作为参考,此RailsCast #196 - Nested Model Form (revised)为您的问题提供了最新的答案。

但你可以看到:

这可以为您提供一个(有点过时的)更好的方法来处理您的问题。

现在,到你的代码:

  1. 作为第一个建议,在这种情况下使用ul代替table可能会更好(并且通常用于布局目的)。< / p>

  2. 避免在视图或帮助程序中使用SQL查询,查询始终属于模型。

  3. 例如,您可以在Player模型中使用按名称排序的玩家范围:

        class Player < ActiveRecord::Base
          scope :name_ordered, -> { order(:name) }
        end
    
    1. 然后,您可以从Controller加载实例变量@players,并在视图中使用它。

    2. 在Ruby代码中使用HTML很难阅读,最终可能会转义\",最好使用content_tag。见example。如果您需要在内部连接多个标记,请使用concat。 一个例子(它可能不是100%正确,但你会得到这个想法):

      player_select = pim.select @players,:id,{include_blank:false},{class:&#39; selected-select&#39;})    content_tag:tr,id:&#34; row_p#{nr}&#34;做      concat(pim.hidden_​​field&#34; placement&#34;,value:nr)      concat(content_tag:td,&#34;#{nr}&#34;)      concat(content_tag:td,player_select)      #...    端

    3. 您可以查看Rails Guides - Form Helpers了解详情。

      希望这有帮助!