简体   繁体   中英

Create or Update Multiple Records at a Single Time Using Strong Parameters in Rails 4

I have two questions:


In Rails 3 you can update multiple records using

Product.update(params[:products].keys, params[:products].values)

How do you do the same thing in Rails 4 using Strong Parameters? How about creating multiple records at the same time? Can you please elaborate your solution with an example in a format like the following:

params = ActionController::Parameters.new(...)
Product.create!(params.require(...)permit(...)

Also, my products model has a column called number which is equal to the order that they are updated. Is there a way to pass a counter value to the number while updating?

Thanks.

Maybe you're thinking about using nested_attributes? That would look something like this:

params.require(:parent_model).permit(
  :id,
  child_models_attributes: [
    :id,
    :parent_model_id,
    :child_model_attribute_1,
    :child_model_attribute_2
  ]
)

with

params = {
  id: parent_model.id,
  child_models_attributes: {
    '0' => {
      id: child_model_1.id,
      parent_model_id: parent_model.id,
      child_model_attribute_1: 'value 1',
      child_model_attribute_2: 12312
    }
  }
}

You would need to allow nested_attributes for the parent model like this though:

class ChildModel < Activerecord::Base
  belongs_to :parent_model
end

class ParentModel < Activerecord::Base
  has_many :child_models
  accepts_nested_attributes_for :child_models
end

Solution w/o accepts_nested_attributes_for

This is my 2nd ever answer on SO, but I came across this problem multiple times, couldn't as of this writing find a reasonable solution and finally figured it out myself after doing a little nested_attributes hypothesizing and wanted to share my best understanding of it. I believe the strong params line you're after is this:

product_params = params.require(:products).permit(product_fields: [:value1, :value2, etc...])

I don't know exactly what your form looks like, but you will need to have a fields_for to nest the params in the product_fields(or any_name):

form_for :products do |f|
  f.fields_for product_fields[] do |pf|
    pf.select :value1
    pf.select :value2
    ...
  end
end

This will allow the permit() to accept a single explicit hash

product_fields => {0 => {value1: 'value', value2: 'value'}}

instead of the key/value pairs

0 => {value1: 'value', value2: 'value'}, 1 => {value1: 'value', value2: 'value'}, etc...

which you'd otherwise have to name individually:

.permit(0 => [value1: 'value', value2: 'value'], 1 => [...], 2 => [...], ad infinitum)

This allows you to update multiple products without having to use a parent model accepting nested attributes. I just tested this on my own project in Rails 4.2 and it worked like a charm. As for creating multiple: How would I save multiple records at once in Rails? .

As for a counter, you may need to iterate over each model individually:

product_params[:product_fields].keys.each_index do |index|
  Product.create!(product_params.merge(counter: index))
end

Thought it's been so long you probably resolved that on your own. :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM