控制器批量更新的最佳实践

时间:2011-11-01 11:49:43

标签: ruby ruby-on-rails-3 model-view-controller rest

我想知道在控制器中允许批量编辑/更新的最佳做法是什么。我真的找不到关于这个主题的文章或指南。

5 个答案:

答案 0 :(得分:39)

我看到你用REST标记了你的问题。

要以REST形式执行此操作,您需要考虑集合或更新本身作为资源。

假设您正在使用Product对象。

您可能会将/Pate_batches / [某些标识符] PUT,这会调用ProductBatchesController #update,但是你会想知道[某些标识符]中的内容。您可以将ProductBatch设为singular resource,然后您就不需要ID。

最好是POST到/ product_bulk_updates,这将调用ProductBulkUpdatesController #create

class ProductBulkUpdatesController < ApplicationController

  def create
    # your magic here
    # - update_all if you are making the same change to all Products
    # - looping through the hashes in params[products] if you are passing in distinct changes to each.
  end

end

这是另一个主题: Bulk Collection Manipulation through a REST (RESTful) API

答案 1 :(得分:9)

我不认为有一种标准方式。您可以使用update_attributes(示例与 PostsController ):

def update_bulk
  @posts = Post.where(:id => params[:ids])

  # wrap in a transaction to avoid partial updates (move this logic to the model!)
  if @posts.all? { |post| post.update_attributes(params[:post]) }
    redirect_to(posts_url)
  else
    redirect_to(:back)
  end
end

或者使用update_all,但请注意,不会调用回调和验证:

def update_bulk
  Post.where(:id => params[:ids]).update_all(params[:post])
  redirect_to(posts_url)
end

答案 2 :(得分:6)

如果你有幸在Rails 3中工作,那么你应该确保在Rails 2中查看ActiveRecord :: Relation#update_all或ActiveRecord :: Base#update_all:

构建单个SQL更新语句比完整SQL往返更新元素要好得多。

重要说明:这确实是使用SQL更新语句的批量更新。它不会实例化任何ActiveRecord对象,因为更新仅在SQL中执行。因此,不会调用ActiveRecord回调和验证。

上述网址中的示例:

# Update all customers with the given attributes
Customer.update_all :wants_email => true

# Conditions from the current relation also works
Book.where('title LIKE ?', '%Rails%').update_all(:author => 'David')

注意:就我在互联网上的帖子所知,这个功能介于Rails 3.0.3,3.0.7 - 3.0.9中的bug和破坏之间。

直到3.1.0我才发现这个功能,所以我无法证实。

答案 3 :(得分:2)

对@Robert Head的答案进行了一些小的补充。在Rails官方参考中,有一章&#34; 什么是REST?&#34; http://guides.rubyonrails.org/v2.3.11/routing.html#what-is-rest

本章参考了REST's author Roy Fielding的博士论文。在章节&#34; 5.2.1.1资源和资源标识符&#34;我们可以阅读:

http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_2_1_1

  

REST中信息的关键抽象是一种资源。任何   可以命名的信息可以是资源:文档或图像,   暂时的服务(例如&#34;今天洛杉矶的天气&#34;), a   其他资源的集合,一个非虚拟对象(例如一个人),   等等。

因此,在这里定义一个ProductCollection资源 - 拥有7个自己的RESTful动作 - 很适合整个REST概念。

答案 4 :(得分:0)

我没有试过这个,并不是真正的模型级批量操作,但它看起来很有趣。

batch_api gem允许我们累积请求并一次发送。 Facebook也有类似的机制。