1

In my Vue frontend I have set this method:

bulkAction(selected) {
  this.$secured.patch('/api/v1/bulk_edit', {
     data: this.selected,
     sold: this.bulk_sold
  })
    .then((response) => {
    console.log(response.data)
});
    }

selected: [] is an array of objects. sold is a boolean and an attribute in the objects in the array selected.

So for instance if sold is true, I want to set sold as true for all objects in the array.

With this in place I am able to send to the server an array of objects(data) and a param sold.

In rails controller I have set this methd:

def bulk_edit
    @item_locations = ItemLocation.where(params[:data])
    bulk_params = params.permit(:sold)
    @item_locations.each do |item_location|
      item_location.update(bulk_params)
    end
end

Which returns:

NoMethodError (undefined method `update' for #<ActionController::Parameters:0x00007fa094596140>):

I guess this is the wrong part:

    @item_locations = ItemLocation.where(params[:data])

But I'm not sure on how to convert it.

The request looks like:

    app/controllers/api/v1/items_controller.rb:47:in `bulk_edit'
Started PATCH "/api/v1/bulk_edit" for 127.0.0.1 at 2020-01-20 16:40:28 +0800
Processing by Api::V1::ItemsController#bulk_edit as HTML
  Parameters: {"data"=>[{"id"=>"44ed3183-cce2-4f3b-b673-6052d8cc5fe5"}, {"id"=>"ed7438dc-60ed-4887-bf86-90b6161c0074"}], "sold"=>false, "item"=>{}}

Any suggestion?

12
  • You must first get those records as ActiveRecord objects in invoke update on them. Otherwise you're just trying update what you receive from the request, which is converted into an ActionController::Parameters object. Commented Jan 20, 2020 at 7:41
  • What's the identifier you're sending (params[:data]) in order to query the records from the DB? Commented Jan 20, 2020 at 7:41
  • Could you show how to convert it in an answer? Commented Jan 20, 2020 at 7:41
  • @SebastianPalma it's id Commented Jan 20, 2020 at 7:42
  • But if I can't convert the objects and I have to iterate to covert to Active Record at that point I can just pass the ids instead of the objects. Commented Jan 20, 2020 at 7:44

2 Answers 2

1

According to what you're sending, you need to first map what goes inside data in order to get each ItemLocation id, so you can make an IN query:

ItemLocation
  .where(id: params['data'].map { |item_location| item_location['id'] })
  .update_all(sold: params['sold'])

After that, you can use update_all to perform a single query to update every ItemLocation you got, with the value of sold equals to what's in the params,

Sign up to request clarification or add additional context in comments.

Comments

0

Tried to simplify it

def bulk_edit
    @item_locations = ItemLocation.where(id: params[:data]).update_all(params.permit[:sold])
end

3 Comments

Thanks for the answer but this returns no records to update..
You need to map what comes in params[:data]. where doesn't automatically retrieve the content from it.
TS said that he has updated request body and now sends only array of ids. So I suppose we can do where on them. Or I misunderstood something

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.