使用rails中的表单批量更新对象

时间:2009-10-01 23:26:08

标签: ruby-on-rails

我有一个人模型和一个报价模型。每个人都可以有很多与之关联的引号,而这些引号又与作者,文本,与其关联的URL相关。在实践中,实际上只有一个人有一个引号对象,但所有人都可能有一个。

我正在尝试在引号上使用简单的大容量温和工具。用户可以输入引号,管理员可以输入特定人的所有引号(但在实践中,只有一个人会拥有它们)并选中一个设置布尔批准为0或1的框。报价实际上是显示的,它们会被这个字段过滤掉。

我试图创建一个可以批量更新这些内容的表单。我得到了表单以显示所有这些:

<% form_for :quotes, :html => { :method => :put }, :url => {:controller => "quote", :action => "bulk_update", }  do |quote_form| %>
   <% @person.quotes.each do |quote| %>
<p>
   <% fields_for "quotes[id][]", quote  do |fields| %>
           Text....
           <%= fields.check_box :approved %><br><br>

  <% end %>
</p>

<% end %>
<%= submit_tag 'Update' %>
<% end %>

我的批量更新控制器中只有一个非常通用的东西,它基本上就像一个普通的更新控制器。我不知道该放什么。我可以尝试把所有引号都放在我可能应该但我不知道如何到达那个变量,因为我正在从Person视图中执行所有这些操作。控制器是这样的:

def bulk_update
@quote = Quote.find(params[:id])
end

我想我对那里应该存在的ID以及应该传递的内容感到困惑。这个人ID应该是其中的一部分吗?就像我说的那样,我并不在乎技术上是否所有引号都显示在该页面上,它们不需要按用户排序。

我得到的参数如下:

“quotes”=&gt; {“id”=&gt; {“6”=&gt; {“approved”=&gt;“0”},..

但它抱怨没有找到没有ID的报价。我不关心ID,因为我想批量更新所有ID。看起来这个特殊的结构会映射几个ID,但也许(可能)我必须改变我的控制器以弥补这一点,但不确定如何。当我尝试删除散列的引号并且只有“id”=&gt; {“6”=&gt; {“approved”=&gt;“0”}时,它也不起作用,作为我的参数

编辑:我发现了一个名为update_all的声明,但我不知道如何有选择地将它传递给我需要的东西......

3 个答案:

答案 0 :(得分:4)

我发现以下方法也适用于错误处理:

def bulk_update
  quotes = params["quotes"]["id"]
  quotes.each do |quote_id,quote_attrs|
    quote = Quote.find(quote_id)
    quote.update_attributes(quote_attrs)
    # Other logic of interest like error handling
    # . . .
  end
  # Don't forget to render or redirect to the proper view
end

<强>更新

执行此操作的正确方法是将更新逻辑移至模型:

class QuotesController < ApplicationController
  def bulk_update
    errors = Quote.bulk_update(params["quotes"]["id"])
    # Other logic of interest like error handling
    # . . . 
    # Don't forget to render or redirect to the proper view
  end
end

class Quote < ActiveRecord::Base
  def bulk_update
    errors = {}
    quotes.each do |quote_id,quote_attrs|
      quote = Quote.find(quote_id)
      unless quote.update_attributes(quote_attrs)
        errors[quote_id] = qoute.errors
      end 
    end
    errors
  end
end

答案 1 :(得分:0)

我会做出类似的事情:

def self.bulk_update(attributes)
  where(id: attributes.keys).each_with_object({}) do |quote, errors| 
   unless quote.update_attributes(attributes["#{quote.id}"])}
     errors["#{quote.id}"] = entry.errors
   end
end

在此方法中,您只会加载相关的引号。

Gregory Horion -

答案 2 :(得分:0)

看完这段代码后:

def bulk_update
  quotes = params["quotes"]["id"]
  quotes.each do |quote_id,quote_attrs|
    quote = Quote.find(quote_id)
    quote.update_attributes(quote_attrs)
  end
end

我认为这样做可能更简洁:

Quote.where(:condition => "value").collect{|x| x.update_attributes(quote_attrs)}