Reputation: 1150
I have an really big array of objects read from a CSV file and want to save it to the database. This is what I am doing:
# Read CSV
... each do |values|
new_value = Model.new
... # fill properties
@new_values.push new_value # put it into the array
end
# now save them to the database
@new_values.each do |new_value|
new_value.save :validate => false
@added_counter += 1
end
But this is really slow because it will make a statement for each element in the array. How can this be done in a fast and correct way?
Upvotes: 0
Views: 2607
Reputation: 1150
This is a solution based on the comments of mu is too short (Thanks!). I use a handmade SQL-Statement and execute it.
insert_statement = "INSERT INTO table_name (custom_property_from_parameter"
# the properties from the model are fetched by a method, to keep it a little bit generic, loop trough them and give their names to the statement
Model.parameter_names.each do |parameter|
insert_statement += "," + parameter
end
insert_statement += ") VALUES "
@new_values.each do |new_value|
insert_statement += "(" + params[:custom_property]
Model.parameter_names.each do |parameter|
# Rails' nil has to be converted into NULL for SQL
if nil == new_value.send(parameter)
insert_statement += ",NULL"
else
insert_statement += "," + new_value.send(parameter).to_s
end
end
insert_statement += "),"
@added_counter += 1
end
# Remove the last , with ;
insert_statement = insert_statement[0..-2]
insert_statement += ";"
# now execute the statement
ActiveRecord::Base.connection.execute insert_statement
This solution takes approximately a third of the time. But it seems a little bit like a hack to me.
Upvotes: 0
Reputation: 50057
Maybe activerecord-import could be useful for you.
It allows to do something like:
books = []
10.times do |i|
books << Book.new(:name => "book #{i}")
end
Book.import books
Upvotes: 3