开发者

Making decisions based on find_or_create

开发者 https://www.devze.com 2023-02-21 20:35 出处:网络
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

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
0

精彩评论

暂无评论...
验证码 换一张
取 消