Принятие решений на основе find_or_create - PullRequest
0 голосов
/ 05 апреля 2011

Я пытаюсь сделать что-то вроде этого (создание нескольких файлов одновременно):

@files = params[: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

Выше не совсем работает.Когда файл «найден», а не «создан», это должно вызывать ошибку (т. Е. Потому что файл НЕ является новым).Тем не менее, он все равно не добавляется к сбоям (find_or_create в этом случае никогда не дает сбой).

Как я могу элегантно выполнить вышеизложенное?

Примечание: я хочу избежатьпредоставление пользователям неприятно большого списка ошибок, если, например, они по ошибке пытаются создать один и тот же список из 100 файлов дважды.Мне кажется, что было бы лучше просто перечислить ошибки в предложении, чем отображать отдельное уведомление об ошибке для каждого из них.

Ответы [ 2 ]

1 голос
/ 05 апреля 2011

find_or_create_by_name всегда будет возвращать найденную или созданную запись, если она не удалась из-за проверки или чего-то еще.

Если добавление validates_uniqueness_of: name не работает для вас, учтите следующее:

if File.find_by_name file
  failures << file
else
  unless File.create(:name => file, ...)
    failures << file
  end
end

Но, если обстоятельства позволят вам добавить подтверждение уникальности, я бы согласился с этим.

1 голос
/ 05 апреля 2011

Можете ли вы добавить validates_uniqueness_of :name к File? Тогда вы могли бы просто сделать

unless File.create(:name => file, ...)
  failures << file
end
...