Mischa,
клонирование это зверь.
record.errors запоминается, а переменная экземпляра @errors также клонируется.
file1.errors = new_file.errors
это будет не ноль, поскольку create
называется проверкой на file1
.
что теперь происходит, когда вы клонируете file1 и говорите new_file.save!
?
Глубоко внутри valid?
вызывает error.clear для нового_файла, но он по-прежнему указывает на тот же объект ошибки, что и файл1.
Теперь, злобно, валидатор присутствия реализован так:
def validate(record)
record.errors.add_on_blank(attributes, options)
end
который (очевидно) может получить доступ только к ошибкам.
http://apidock.com/rails/ActiveModel/Errors/add_on_blank
так, хотя проверки выполняются для new_file как записи, проверка присутствия проходит с
new_file.errors.instance_eval { @base } == file1
и для file1.folder_id
НЕ пусто.
Теперь ваш второй тест пройден, потому что если вы читаете запись файла из базы данных, file2.errors
равен нулю, поэтому, когда вы клонируете ее и вызовете проверки для клона, объект ошибок создается заново с правильной базой (клон ) для которого folder_id
будет пустым из-за строки new_file.folder = target_folder
.
Ваша проблема решается простым добавлением
def copy(target_folder)
new_file = self.clone
new_file.instance_eval { @errors = nil } # forces new error object on clone
new_file.folder = target_folder
new_file.save!
end
надеюсь, это помогло