如何在 Rails 3 中更新表中的多个条目



我有一个 Rails 应用程序,它试图在 User 表中一次更新多个用户。我尝试给出多个用","分隔的 id,但失败并出现"没有路由匹配"之类的错误,我创建了一个自定义方法"分配",将路由指定为 ,

"assign/:id" => "users#assign" , :via => [:put] 

我正在尝试通过邮递员REST客户端进行更新。

我的 PUT 请求,

http://localhost:3000/assign/6,7,8    ---   PUT

数据:

{
   "users":[
    {
       "trainerid":4
    },
    {
       "trainerid":5
    },
    {
       "trainerid":6
    }
    ]
}

牟控制器

def assign
    @ids = params[:id].split(",")
    @users = params[:users]
    @ids.each_with_index do |i|
      @user = User.find(i)
      @user.updateattributes(@users[index])
    end
    render :json => { :status => :ok, :message => "User Updated Successfully"}.to_json 
end

在这里,我正在尝试使用id: 4 ,5 ,6更新用户表中的trainerid

是否可以以其他方式更新。

任何帮助不胜感激.....

为什么要把ID放在URL中?拆分字符串感觉不对。为什么不有一个更简单的路由,只给用户/分配?然后在您的 JSON 中,您可以拥有:

{ "users":[
  { "id":6, "trainer_id":4 },
  { "id":7, "trainer_id":5 },
  { "id":8, "trainer_id":6 }
]}

并这样处理它:

def assign
  params[:users].each do |hash|
    User.find(hash['id']).update_attributes hash
  end
end

显然它需要错误处理等,但这是基本方法。请注意,update_attributes只会更新标记为attr_accessible的属性,因此您不必担心哈希中是否存在 ID。

我已经测试了您的路由,它没有给我路由错误。这是我所拥有的:

match "assign/:id" => "users#assign" , :via => [:put] 

使用此路由,正确assign/1,2,3的请求将路由到控制器的assign操作。此时,您需要拆分params[:id](就像您所做的那样)。

但是,您不需要使用实例变量,也不需要each_with_index

def assign
  ids = params[:id].split(",")
  users = params[:users]
  ids.each do |i|
    user = User.find(i)
    user.update_attributes(users[index])
  end
  render :json => { :status => :ok, :message => "User Updated Successfully"}.to_json
end

但是,我发布此答案只是为了说这是可以做到的。老实说,我同意@micapam的观点,你真的不需要像这样拆分id。

路线

"assign/:id" => "users#assign" , :via => [:put] 

一次只能获取一个 ID。您不能为此路由传递多个 ID。

更新路由以使用edit_multiple和update_multiple操作:

resources :users do
  get edit_multiple, :on => :collection
  post update_multiple, :on => :collection
end

现在创建edit_multiple操作,该操作使用要更新的用户数据设置@users实例变量:

def edit_multiple
  @users = User.all #get the users with specified criteria.
end

在您的edit_multiple.html.erb中:

<%= form_tag :action => "update_multiple" do %>
  <% @users.each_with_index do |user, index| %>
    <%= fields_for "user[#{index}]", user do |f| %>
      <%= f.hidden_field :id, :value => user.id %>
      <div class="field">
        <%= f.label :name %><br />
        <%= f.text_field :name %>
      </div>
      <div class="field">
        <%= f.label :dob %><br />
        <%= f.date_select :dob %>
      </div>
    <% end %>
  <%end%> 
  <div class="actions">
    <%= submit_tag "submit" %>
  </div>
<% end %>

在控制器中:

def update_multiple
  @users = {}
  error_count = 0
  params[:users].values.each do |user_params|
    user = User.find(user_params[:id])
    unless user.update_attributes(user_params)
      error_count += 1 #increment error count if fails to update
    end
    @users << user #add user to @users array to render the edit if fails
  end
  if error_count == 0
    redirect_to users_path, :notice => 'Users saved successfully'
  else
    render :edit_multiple #@users will play its role here
  end
end

这可能不是最好的方法。希望这会有所帮助。您也可以使用 JSON 响应。

相关内容

  • 没有找到相关文章

最新更新