根据find_or_create做出决策

时间:2011-04-04 22:17:34

标签: ruby-on-rails ruby-on-rails-3 error-handling

我正在尝试这样做(一次创建多个文件):

@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 个答案:

答案 0 :(得分:1)

您可以将validates_uniqueness_of :name添加到File吗?然后你可以做

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

答案 1 :(得分:1)

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

但是,如果情况允许你添加唯一性验证,我会接受它。