Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveRecord create: pass in an array of attributes

I would like to know if there is a Rails way to create multiple records by passing in an array of attributes.

For instance, instead of

MyModel.create!(attr_1: some_attr, attr_2: 1)
MyModel.create!(attr_1: some_attr, attr_2: 2)
MyModel.create!(attr_1: some_attr, attr_2: 3)
MyModel.create!(attr_1: some_attr, attr_2: 4)

I would like to do something like:

MyModel.create!(attr_1: some_attr, attr_2: [1,2,3,4])

But it does not work. Is there a similar way to achieve this without looping?

like image 678
Sung Cho Avatar asked May 02 '15 10:05

Sung Cho


People also ask

How to pass a type object to a class in ActiveRecord?

You can also pass a type object directly, in place of a symbol. When ActiveRecord::Base.where is called, it will use the type defined by the model class to convert the value to SQL, calling serialize on your type object. For example:

How to convert an ActiveRecord to an array in rails?

You can also convert any ActiveRecord objects to a Hash with serializable_hash and you can convert any ActiveRecord results to an Array with to_a, so for your example : And if you want an ugly solution for Rails prior to v2.3 Show activity on this post.

How to convert ActiveRecord objects to Ruby hashes?

You should use as_json method which converts ActiveRecord objects to Ruby Hashes despite its name

Is it possible to hash a result in an ActiveRecord?

For current ActiveRecord (4.2.4+) there is a method to_hash on the Result object that returns an array of hashes. You can then map over it and convert to symbolized hashes:


2 Answers

According the documentation you can create records from an array of hashes:

The attributes parameter can be either be a Hash or an Array of Hashes. These Hashes describe the attributes on the objects that are to be created.

 MyModel.create([{attr_1: some_attr, attr_2: 4}, {attr_1: some_attr, attr_2: 5}])
like image 95
Philidor Avatar answered Nov 16 '22 03:11

Philidor


At the time the question was asked ActiveRecord did not have any built-in features to efficiently insert multiple records at once. As of today Rails 6 is the current stable release and it comes with Model#insert_all! which is a method for bulk inserting.

You'll find the documentation for it here https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-insert_all-21

It is worth to mention that Rails 6 also implements Model#upsert_all! which efficiently inserts or updates in case the the record exists.

like image 21
Robin Avatar answered Nov 16 '22 04:11

Robin