Hey there, Anybody wanted to make a bulk insert_all, upsert_all returning:… and get instantiated models back?
e.g
Slot.insert_all({...},{...},{...},{...} returning: Slot)
=> [Slot, Slot, Slot, Slot]
Slot.insert_all({...},{...},{...},{...} returning: Slot.includes(:show))
=> [Slot, Slot, Slot, Slot] with show relation included
I created this tiny bit of code, which I thought is too small to create a gem and engine.
- Set the returning option to a model class, it uses column names and returns instantiated model objects
- Set the returning option with a ActiveRecord::Relation, it uses the column names of the #select or the column_names of klass. options such as #includes is available
[EDIT - before I pasted the wrong version]
ActiveSupport.on_load(:after_initialize) do
ActiveRecord::InsertAll.module_eval do
def returning
if @returning.is_a?(ActiveRecord::Relation)
@returning.select_values.presence || @returning.klass.column_names
elsif @returning.is_a?(Class) and @returning < ActiveRecord::Base
@returning.column_names
else
@returning
end
end
alias _execute execute
def execute
if @returning.is_a?(ActiveRecord::Relation)
@returning.send(:instantiate_records, _execute)
elsif @returning.is_a?(Class) and @returning < ActiveRecord::Base
@returning.send(:relation).send(:instantiate_records, _execute)
else
_execute
end
end
end
end
If this is useful, perhaps introduce it to Rails. Thanks, Martin