I'm writing an import routine that will allow a user to upload a CSV file to load their database. Ea开发者_如何转开发ch row of the CSV corresponds to a model.
I'm using FasterCSV to read the file and split the data into individual models, which is working great. I'm just having trouble deciding on the best approach to handle errors.
Right now I have this going, but it really seems wrong to me:
def import(collection)
begin
self.transaction do
collection.collect{|object| object.save!}
end
rescue ActiveRecord::RecordInvalid => invalid
return false
end
return true
end
Is there a better way to save a collection of models?
Using an exception in a loop is going to cause all kinds of headaches for you when you want to track down the problematic record. What you might do is try and save them all, but report on those with errors:
def import(collection)
failed = nil
transaction do
failed = collection.reject { |r| r.save }
unless (failed.empty?)
raise ActiveRecord::Rollback
end
end
failed
end
This presumes you're interested in having a look at the errors. If any records fail, they will be returned in an Array. Otherwise you'll get a nil, which means no errors.
If you don't care, you can always just do a quick and dirty save:
def import(collection)
transaction do
collection.each(&:save!)
end
end
This will pop an ActiveRecord::RecordInvalid exception for the first failure.
For this problem I think the better approach is yours. Maybe not all the records in the csv aré going yo validare, and those that not doesnt matter (log them in order to know the errors)
精彩评论