【问题标题】:Rails Restful actions Index PutRails Restful 操作 Index Put
【发布时间】:2009-11-20 17:22:37
【问题描述】:

我经常遇到想要一次更新多条记录的情况 - 就像 GMail 将许多消息设置为“已读”或“未读”一样。

Rails 通过 ActiveRecord 类的“更新”方法来鼓励这一点 - Comment.update(keys, values)

示例 - http://snippets.dzone.com/posts/show/7495

这是很棒的功能,但很难映射到宁静的路线。从某种意义上说,我希望看到对集合执行 :put 操作。在路由中,我们可能会添加类似

map.resources :comments, :collection => { :update_many => :put }

然后在表单中,你会这样做......

<% form_for @comments do |f| %>
  ...

这在很多层面上都不起作用。如果你这样做: :collection => { :update_many => :put },rails 将提交一个帖子到 index 操作(CommentsController#index),我希望它去 'update_many' 操作。相反,您可以执行 :collection => { :update_many => :post }。这至少会在控制器中执行正确的操作。

并且,您必须执行以下操作,而不是

<% form_for :comments, :url => { :controller => :comments, :action => :update_many } do |f| %>

这样就可以了

仍然不完美 - 感觉有点像我们没有按照“Rails 方式”进行操作。 :post 和 :delete 似乎在集合控制器上也有意义。

我在这里发帖,看看我在设置时是否遗漏了什么。关于如何从容地进行收集级别 :post、:put、:delete 的任何其他想法?

【问题讨论】:

  • 我意识到我的回答只是为激发您的问题的问题提供了另一种解决方案。我已经对其进行了编辑以反映这一点。

标签: ruby-on-rails forms rest


【解决方案1】:

我遇到过你描述的几种情况。前几次我实现的表单几乎与您建议的相同。

在我第三次遇到这个问题时,我意识到我正在更新的每个项目都与其他项目有一个共同的 belongs_to 关系。通常是用户。这正是您需要以 RESTful 方式理解这一点的顿悟。它还将帮助您清理表单/控制器。

不要将其视为更新一堆消息,而应将其视为更新一个用户。

这是我过去用来突出差异的一些示例代码。假设我们想要对属于 current_user 的消息进行批量操作...

从 Rails 2.3 开始,我们可以添加

 accepts_nested_attributes_for :messages

到用户模型。确保 messages_attributes 是 attr_accessible 的一部分,或者不是 attr_protected。

然后创建路由:

 map.resources :users, :member => {:bulk_message_update, :method => :put}

然后将动作添加到控制器。具有 AJAX 功能;)

 def bulk_message_update
   @user = User.find(params[:id])
   @user.update_attributes(params[:user])
   if @user.save 
     respond_to do |format|
       format.html {redirect}
       format.js {render :update do |page|
          ...
       } 
     end       
   else
     ....
 end 

那么你的表单将如下所示:

<% form_for current_user, bulk_message_update_user_url(current_user), 
     :html => {:method => :put} do |f| %>
  <% f.fields_for :messages do |message| %>
    form for each message
  <% end %>
  <%= sumbit_tag %>
<% end %>

【讨论】:

  • 如果消息是用户的子资源,那么对 /user/123/messages 执行 PUT 似乎是合适的。你怎么看?
【解决方案2】:

我经常将基于集合的 update_multiple 和 destroy_multiple 操作添加到其他 RESTful 控制器中。

查看Railscast 通过复选框进行更新。它应该让您知道如何处理它,如果遇到麻烦,请返回并添加到这个问题!

【讨论】:

  • 感谢您 - 看起来使用 'form_for' 不适用于 :put 操作。当我切换到“form_tag”(如 Ryan B. 演示的那样)时,它现在正在执行正确的操作并正常工作。我没有试图弄清楚为什么。一件小事 - 我喜欢使用 'fields_for' 块为每条记录 ( f.text_field ) 生成输入字段。 Ryan 在他的截屏视频中没有使用 fields_for (可能是因为它早于帮助程序)并使用了 _tag 方法。 'fields_for' 在这里可以使用。
猜你喜欢
  • 1970-01-01
  • 2016-05-05
  • 2011-04-29
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-19
  • 2017-04-04
相关资源
最近更新 更多