我遇到了一个问题,我无法得到一个好的解决方案,希望有比我更多经验的人可以提供帮助。
我正在创建一个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)
但这感觉很糟糕,而且代码真的不直观。有人能指出我更聪明的解决方案吗?有没有办法可以重用辅助类方法来添加行?
答案 0 :(得分:1)
作为参考,此RailsCast #196 - Nested Model Form (revised)为您的问题提供了最新的答案。
但你可以看到:
这可以为您提供一个(有点过时的)更好的方法来处理您的问题。
现在,到你的代码:
作为第一个建议,在这种情况下使用ul
代替table
可能会更好(并且通常用于布局目的)。< / p>
避免在视图或帮助程序中使用SQL查询,查询始终属于模型。
例如,您可以在Player
模型中使用按名称排序的玩家范围:
class Player < ActiveRecord::Base
scope :name_ordered, -> { order(:name) }
end
然后,您可以从Controller加载实例变量@players
,并在视图中使用它。
在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) #... 端
您可以查看Rails Guides - Form Helpers了解详情。
希望这有帮助!