我想知道在控制器中允许批量编辑/更新的最佳做法是什么。我真的找不到关于这个主题的文章或指南。
答案 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也有类似的机制。