根据下拉列表中的选择动态初始化未保存的父对象的子记录

时间:2017-10-29 12:05:40

标签: javascript ruby-on-rails ajax coffeescript

我有一个问题,我觉得不应该像我现在感觉那么复杂。我想根据父表单下拉列表中的选择初始化子记录,然后显示这些子项(目前总是2)以便进一步填充。

这里和网络上的其他地方有几个主要相关的答案,但到目前为止,我在构建工作解决方案方面失败了。

主要构建块如下。

game.rb(父母)

class Game < ApplicationRecord
  has_many :game_players, dependent: :destroy
  belongs_to :scenario

  accepts_nested_attributes_for :game_players
end

game_player.rb(儿童)

class GamePlayer < ApplicationRecord
  belongs_to :game
  belongs_to :user
  belongs_to :force
end

在新游戏的表单中,我有以下下拉列表

<div class="form-group">
  <%= form.label :scenario_id %>
  <%= form.collection_select :scenario_id, Scenario.all, :id, :name, {},     { class: "form-control" }   %>
</div>

从此下拉菜单中选择过滤game_players的可能力量(每个场景都有两个相反的力量)。

我抓住了game.coffee

中的scenario_id
jQuery ->
  scenarios = $('[name*=scenario_id]').html()
  $('[name*=scenario_id]').change ->
    scenario_id = $('[name*=scenario_id] :selected').val()
    params = 'scenario_id=' + scenario_id
    $.ajax {
      url: "/games/prepare_players",
      data: params
      success: () ->
    }

在这里,我被困住了。根据我所读到的内容,我试图在games_controller.rb中启动此操作。

def prepare_players
  forces = ScenarioForce.where(scenario_id: params[:scenario_id])
  forces.each do |force|
    @game.game_players << GamePlayer.new( force_id: force.id)
  end
  respond_to do |format|
    format.js
  end
end

还应该在prepare_players.js.erb

中呈现此内容
$('[name=player-cards]').html("<%= escape_javascript(render partial: 'players', locals: {form: form}).html_safe %>")

哪个应该显示两个玩家的形式,可以从双方用户中选择玩家。

<div name="player-cards">
  <h3>Players</h3>
  <% @game.game_players.each do |player| %>
    <p><%= player.force.name %></p>
    <%= form.fields_for player do |pf| %>
      <div class="form-group">
        <%= pf.label :name %>
        <%= pf.collection_select :user_id, User.all, :id, :full_name, {},     {class: "form-control"}  %>
      </div>
    <% end %>
  <% end %>
</div>

但正如我提到的那样,我陷入了Ajax通话。我的控制器操作没有被触发,而是我得到了id = prepare_players的show-action。在routes.rb我有这个

get 'games/prepare_players', to: 'games#prepare_players'

更新根据Sebastiáns的建议,我现在正在使用games_controller进行正确的操作。但正如我所担心的,我不能在不知道相关身份证的情况下向我的父母添加新的game_players。如果我只有一个,那么传递id很容易,但是我没有,因为父母还没有被保存。

我目前正在使用Rails 5.1.4。

高度赞赏指导我实现这一目标的任何指示。

1 个答案:

答案 0 :(得分:1)

确保正在为任何其他路由定义您用于AJAX请求的路由,例如resource :games。如果路线在此之后,那么它将触发set_game方法并将您重定向到游戏#show,在那里您将收到如下错误:

  

4ms完成404未找到(ActiveRecord:0.3ms)

     

ActiveRecord :: RecordNotFound(无法找到游戏   的 'id'= prepare_players):

     

app / controllers / games_controller.rb:65:在`set_game'

请注意games_controller.rb:65:in set_game'。。