Making decisions based on find_or_create
I am trying to do something like this (creating many files at once):
@files = pa开发者_运维技巧rams[:files].split(/\s*,\s*/) # comma-separated list is received
failures = []
@files.each do |file|
unless File.find_or_create_by_name(:name => file, ...)
failures << file
end
end
if failures.present?
errors.add(:base, "The following files are already in use: #{failures.to_sentence}
end
The above isn't quite working. When a file is 'found' rather than 'created', this is something that should prompt an error (i.e. because the file is NOT new). However, it is still not added to failures here (find_or_create
never fails in this case).
How can I do the above in an elegant way?
Note: I want to avoid presenting users with an obnoxiously-large list of errors if, for example, they mistakenly try to create the same list of 100 files twice. I feel that simply listing the errors in a sentence would be better than displaying an individual error notice for each one.
find_or_create_by_name will always return the found or created record unless it failed because of a validation or something.
If adding validates_uniqueness_of :name doesn't work for you, consider this:
if File.find_by_name file
failures << file
else
unless File.create(:name => file, ...)
failures << file
end
end
But, if circumstances allow you to add a uniqueness validation, I would go with that.
Can you add validates_uniqueness_of :name
to File
? Then you could just do
unless File.create(:name => file, ...)
failures << file
end
精彩评论