Bulk update objects using a shape in rails

I have a human model and a quotes model. Each person can have many quotes associated with them, which in turn is associated with things like Author, Text, Url. In practice, only one person actually has a quote object, but all people can potentially have it.

I try to keep the quotes dirty, simple volumetric instrument. As is the case, users can enter quotes, and the admin can go and have all the quotes of a particular person (but, in practice, only one of them will have them) and check the box that sets the boolean asserted to 0 or 1 When quotes are actually displayed, they are filtered by this field.

I am very confused while trying to create a form that updates the whole thing in bulk. I got a form to display them all like this:

<% 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 %>

      

I just have an incredibly generic character in my bulk update controller, which is basically like a regular update controller. I'm not sure what to put in there. I could try to put in all the quotes I probably need, but I don't know how to get to this variable, since I am doing all of this from the Person view, etc. The controller looks something like this:

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

      

I am guessing that I am confused with the ID that should be there and what should be passed. Should the person ID be part of this? As I said, I don't care if technically all the quotes will appear on this page, they don't need to be sorted by user.

I get parameters that look like this:

"quotes" => {"id" => {"6" => {"approved" => "0"}, ..

but it complains about not finding a quote without an id. I don't care about the ID as I want them all to be updated. It seems that this particular structure will display multiple ids, but maybe (maybe) I should change my controller to compensate for this, but don't know how. It also doesn't work when I try to remove quotes from the hash par tof and just have "id" => {"6" => {"approved" => "0"}, .. as my parameters.

EDIT: I found an instruction called update_all, but I don't know how to selectively pass it what I need ...

+2


source to share


3 answers


I found the following approach should be flexible, especially for error handling:

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

      

Update



The correct way to do this is to move the update logic into the model:

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

      

+4


source


I would do something like this:

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

      



In this method, you are only loading quotes.

Gregory Chorion -

0


source


Looking at this code:

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

      

I thought it would be more concise to do this:

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

      

0


source







All Articles