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

发布于 2024-12-13 05:45:15 字数 52 浏览 2 评论 0原文

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

I am wondering what is the best practice for allowing bulk edit / update in the controller. I really can't find articles or guides on the subject.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

生来就爱笑 2024-12-20 05:45:15

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

要以 REST 方式执行此操作,您需要将集合或更新本身视为资源。

假设您正在使用 Product 对象。

您可能会 PUT 到 /product_batches/[someidentifier],这将调用 ProductBatchesController#update,但随后您会想知道 [someidentifier] 中会包含什么。您可以将 ProductBatch 设为 单一资源,然后就不需要 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

这是另一个线程:
通过 REST (RESTful) API 进行批量收集操作

I see that you tagged your question with REST.

To do it RESTfully, you need to think about the collection or the update itself as the resource.

Say you are working with Product objects.

You might PUT to /product_batches/[some identifier], which would call ProductBatchesController#update, but then you are stuck wondering what goes in [some identifier]. You could make ProductBatch a singular resource and then you wouldn't need an id.

Better might be to POST to /product_bulk_updates, which would call 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

Here's another thread:
Bulk Collection Manipulation through a REST (RESTful) API

酷到爆炸 2024-12-20 05:45:15

我认为没有标准的方法。您可以使用 update_attributes (例如使用 PostsController):

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

  # wrap in a transaction to avoid partial updates (and move 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

I don't think there is a standard way. You may use update_attributes (example with PostsController):

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

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

Or use update_all, but notice that neither callbacks nor validations will be called:

def update_bulk
  Post.where(:id => params[:ids]).update_all(params[:post])
  redirect_to(posts_url)
end
鹿港巷口少年归 2024-12-20 05:45:15

如果您有幸使用 Rails 3,那么您应该确保查看 Rails 2 中的 ActiveRecord::Relation#update_all 或 ActiveRecord::Base#update_all:

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

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

上面 URL 中的示例:

# 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 中处于有缺陷和损坏之间。

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

If you're fortunate enough to be working in Rails 3 then you should make sure to check out ActiveRecord::Relation#update_all or ActiveRecord::Base#update_all in Rails 2:

It's much bettter to construct a single SQL update statement than do a full SQL round trip to update the elements.

Important Note: This is truely a bulk update using a SQL update statement. It will not instantiate any ActiveRecord objects since the update is performed purely in SQL. As such ActiveRecord callbacks and validations will not be called.

Examples from the URL above:

# 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')

Note: As far as I can tell from posts on the internet, this functionality was somewhere between buggy and broken in Rails 3.0.3, 3.0.7 - 3.0.9.

I didn't discover the feature until 3.1.0, so I can't corroborate.

遥远的绿洲 2024-12-20 05:45:15

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

本章引用了REST 的作者 Roy Fielding 的博士论文。在本文的“5.2.1.1资源和资源标识符”章节中我们可以读到:

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

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


因此,在这里定义一个 ProductCollection 资源(及其 7 个自己的 RESTful 操作)将非常适合整个 REST 概念。

Some minor additions to the @Robert Head's answer. In the Rails official reference there's a chapter "What is REST?" http://guides.rubyonrails.org/v2.3.11/routing.html#what-is-rest

This chapter references the REST's author Roy Fielding’s doctoral thesis. In Chapter "5.2.1.1 Resources and Resource Identifiers" of this thesis we can read:

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

The key abstraction of information in REST is a resource. Any
information that can be named can be a resource: a document or image,
a temporal service (e.g. "today's weather in Los Angeles"), a
collection of other resources
, a non-virtual object (e.g. a person),
and so on.

So defining here a ProductCollection resource - with its 7 own RESTful actions - would nicely fit into the whole REST concept.

春花秋月 2024-12-20 05:45:15

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

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

I have not tried this, and it is not truely model level bulk operation, but nevertheless it seems interesting.

The batch_api gem allows one to accumulate requests and send them in one go. Facebook has similar mechanism too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文