Rails使用params hash中的错误id

时间:2015-10-25 10:39:00

标签: ruby-on-rails

在我看来,我有一个用户表,对于每个用户,我添加了一个下拉列表来设置该用户的角色。

<% smart_listing.collection.each do |user| %>
  ...
  <tr>
    <td>
      <%= user.role %>

      <%= simple_form_for user, url: edit_user_role_admin_user_path(user), html: { id: 'edit-role' }, method: :patch do |f| %>
        <%= f.input :role,
          required: false,
          label_html: { class: 'sr-only' },
          label: 'Role',
          selected: user.role,
          input_html: { onchange: "$('#edit-role').submit();" }
        %>
      <% end %>
    </td>
  </tr>
  ...
<% end %>

我已在控制器中定义了自定义操作并设置了路径。

namespace :admin do
  resources :users do
    member do
      patch 'edit_user_role'
    end
  end
end

唯一的问题是错误的id传递给控制器​​。 id始终设置为1,而不是user.id

在网址中使用不同的ID,例如url: edit_user_role_admin_user_path(2),就可以了。

user变量发生了什么?

2 个答案:

答案 0 :(得分:0)

问题是您为所有表单使用相同的ID,然后使用它来挂钩您的javascript处理程序。

当浏览器遇到具有相同ID的多个元素时,查询通常会返回第一个元素。

幸运的是,它很容易清理它:

<%= simple_form_for user, url: edit_user_role_admin_user_path(user), method: :patch do |f| %>
  <%= f.input :role,
   required: false,
   label_html: { class: 'sr-only' },
   label: 'Role',
   selected: user.role,
   class: 'instant-submit'
  %>
<% end %>

如果你使用Turbolinks,你会这样做:

// application.js
$(document).on('page:change', function() {
  $('form').on('.instant-submit', 'change', function(){
    $(this).submit();
  });
});

如果不是:

// application.js
$(document).ready(function() {
  $('form').on('.instant-submit', 'change', function() {
    $(this).submit();
  });
});

答案 1 :(得分:0)

问题是"$('#edit-role').submit();"

由于您的HTML网页将包含多个<form id="edit_role">元素,因此您的javascript基本上会发送第一个表单,我认为该表单的user.id1

要解决此问题,您最好调用父表单...并使用不引人注目的 javascript(位于app/assets/javascripts/application.js file中):

#app/views/users/index.html.erb
<% smart_listing.collection.each do |user| %>
    <%= simple_form_for user, url: user, method: :patch do |f| %>
        <%= f.input :role, required: false, label_html: { class: 'sr-only' }, label: 'Role', selected: user.role %>
      <% end %>
<% end %>

#app/assets/javascripts/application.js
$(document).on("change", "select.sr-only", function(e){
   $(this).parents("form").submit();
});

这将为函数绑定的选择选择合适的表单。

我也这样做,以便您将提交内容发送到update的{​​{1}}操作。每次发送到user操作时更新哪些属性都无关紧要,因此您可以使用以下内容:

users#update

这将允许您摆脱您拥有的成员路线:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def update
      @user = User.find params[:id]
      @user.update user_params
   end

   private

   def user_params
      params.require(:user).permit(:x, :y, :z)
   end
end