Stack Exchange
Rails 4 - Iterate through nested JSON params
I'm passing nested JSON into rails like so:
{
  "product": {
    "vendor": "Acme",
    "categories": 
        {
            "id": "3",
            "method": "remove",
        },
    "categories": 
        {
            "id": "4"
        }
  }
}

in order to update the category on a product. I am trying to iterate through the categories attribute in my products_controller so that I can add/remove the product to multiple categories at once:
def updateCategory
    @product = Product.find(params[:id])

    params[:product][:categories].each do |u|
      @category = Category.find_by(id: params[:product][:categories][:id])
        if params[:product][:categories][:method] == "remove"
          @product.remove_from_category(@category)
        else
          @product.add_to_category(@category)
        end
      end
  end

However, this only uses the second 'categories' ID in the update and doesn't iterate through both. 
Example response JSON:
 {
  "product": {
    "id": 20,
    "title": "Heavy Duty Aluminum Chair",
    "product_price": "47.47",
    "vendor": "Acme",
    "categories": [
      {
        "id": 4,
        "title": "Category 4"
     }
   ]
 }
}

As you can see, it only added the category with ID = 4, and skipped over Category 3.
I'm fairly new to rails so I know I'm probably missing something obvious here. I've played around with the format of the JSON I'm passing in as well but it only made things worse. 

You need to change your JSON structure. As you currently have it, the second "categories" reference will override the first one since you can only have 1 instance of a key. To get what you want, you should change it to:
{
  "product": {
    "vendor": "Acme",
    "categories": [
        {
            "id": "3",
            "method": "remove",
        }, 
        {
            "id": "4"
        }
    ]
  }
}

You will also need to change your ruby code to look like:
def updateCategory
    @product = Product.find(params[:id])

    params[:product][:categories].each do |u|
      @category = Category.find_by(id: u[:id])
      if u[:method] == "remove"
        @product.remove_from_category(@category)
      else
        @product.add_to_category(@category)
      end
    end
end


That makes sense. If I change it to that though, I get an error saying "> no implicit conversion of Symbol into Integer" on this line: "@category = Category.find_by(id: params[:product][:categories][:id])"

@Seanvm I added a bit more to my answer. See if that helps.
