Javascript Rails表单:使用AJAX基于其他集合选择值更新集合选择选项

Javascript Rails表单:使用AJAX基于其他集合选择值更新集合选择选项,javascript,ruby-on-rails,ruby,ajax,ruby-on-rails-4,Javascript,Ruby On Rails,Ruby,Ajax,Ruby On Rails 4,我刚刚开始学习Rails,我和内置工具相处得很好,但是Javascript和AJAX对我来说非常陌生。问题是: 我有一张订单。每个订单都属于一个联系人,可以有不同的帐单和发货地址。集合选择框用于设置这些值。如果我不介意重新加载必要的页面以减少可用的地址选项的话,所有这些都可以很好地工作,这些地址选项应限于属于所选联系人的地址 在不重新加载页面的情况下,最简单和最容易维护的选项是什么 这就是我在被卡住之前试图调整表单的原因。让我们从views/orders/edit.html.erb的摘录开始:

我刚刚开始学习Rails,我和内置工具相处得很好,但是Javascript和AJAX对我来说非常陌生。问题是:

我有一张订单。每个订单都属于一个联系人,可以有不同的帐单和发货地址。集合选择框用于设置这些值。如果我不介意重新加载必要的页面以减少可用的地址选项的话,所有这些都可以很好地工作,这些地址选项应限于属于所选联系人的地址

在不重新加载页面的情况下,最简单和最容易维护的选项是什么

这就是我在被卡住之前试图调整表单的原因。让我们从views/orders/edit.html.erb的摘录开始:

我试图观察联系人选择框中的更改,以便立即保存它们,希望地址选择也能立即反映这些更改。此观察员位于assets/javascript/orders.js.erb中:

当时我希望这就足够了,数据已经保存了,但显然Rails希望我在views/orders/update.js.erb中定义一些进一步的说明——在这里我无能为力。这就是我想到的:

$('#order_billing_address_id').replaceWith('<%= escape_javascript(collection_select(:order, :billing_address_id, Address.where(contact_id: @order.contact_id), :id, :name)) %>');
order\u billing\u address\u id是账单地址的collection\u select框的id,我基本上只想刷新内置的rails collection\u select标签

这实际上是可行的——如果我选择了一个不同的联系人,地址框会立即填充相应的地址——但是只有当联系人没有多个关联地址时。当我选择一个具有多个地址选项的联系人时,地址选择框中会显示上一个只有一个地址的联系人的选项。如果我手动刷新页面,尽管它显示了正确的值,即使对于具有多个地址的联系人也是如此。所以数据肯定被保存了,这告诉我我的update.js.erb可能就是问题所在

在选择各种联系人时,我观察了rails dev服务器的输出,数据似乎得到了很好的处理、保存和检索——我看不出单地址联系人和多地址联系人之间的服务器日志有什么不同。根据这些日志,查询和检索到的记录ID与集合按预期匹配


我做错了什么?或者更一般地说,是否有更好的方法/实践来实现我的目标?请记住,我对Rails和更多Javascript非常陌生。非常感谢您的帮助。

经过进一步调查,问题实际上仅限于远程形式的多地址联系人。在这种情况下,地址选择框在联系人选择期间不会更新。为了简化对问题的搜索,我实际上开始在选择框中填充Address.all,但由于有多个结果,这当然不起作用-只要我添加.limit1,尽管一切都很好。有人知道这里发生了什么吗?我也是新手,但是一些帮助我调试AJAX调用的东西是使用Chrome Dev工具,使用网络选项卡,点击AJAX调用查看标题和响应。如果你能把这些贴在你的答案上,可能会有所帮助。我还使用了RailsPanel chrome扩展,它需要meta_请求gem,但对于快速检查参数值有很大帮助。不是答案,但希望它能帮助:
def update
  @order = Order.find(params[:id])

  respond_to do |format|

    if @order.update_attributes(order_params)
      format.html { redirect_to edit_order_path, notice: "Auftrag aktualisiert." }
      format.json { render json: @order }
      format.js
    else
      render 'edit'
    end
  end
end
$('#order_contact_id').change(function() {
  $(this).parents('form:first').submit();
});
$('#order_billing_address_id').replaceWith('<%= escape_javascript(collection_select(:order, :billing_address_id, Address.where(contact_id: @order.contact_id), :id, :name)) %>');