4

我正在开发一个具有以下黄瓜步骤的项目:

Given /^no registered users$/ do
  User.delete_all
end

作为一个新的 RoR 用户,这看起来有点危险,即使我要在我们的开发数据库上进行测试,因为我们的User表有实际数据。这行代码在做什么?

谢谢!

4

4 回答 4

8

delete_all 来自 activerecord 库而不是来自 FactoryGirl。

这两者之间的区别是:

delete_all(条件 = nil)公共

  • 在不先实例化记录的情况下删除匹配条件的记录,因此不调用destroy方法也不调用回调。
  • 这是一条直接进入数据库的 SQL DELETE 语句,比 destroy_all 高效得多。
  • 但是要小心关系,特别是:不遵守在关联上定义的依赖规则。
  • 返回受影响的行数。

destroy_all(条件 = nil)公开

  • 通过实例化每条记录并调用其destroy方法来销毁匹配条件的记录。
  • 执行每个对象的回调(包括:依赖关联选项和 before_destroy/after_destroy Observer 方法)。
  • 返回被销毁的对象的集合;每个都将被冻结,以反映不应进行任何更改(因为它们无法持久化)。

笔记

当您一次删除多条记录时,每条记录的实例化、回调执行和删除可能会很耗时。它为每条记录生成至少一个 SQL DELETE 查询。如果您想快速删除许多行,而不关心它们的关联或回调,请改用 delete_all。

于 2012-05-15T13:10:23.830 回答
2

delete_all不是来自 FactoryGirl,它是一个活动记录命令,它会从您的数据库中删除用户。如果您从 cucumber 运行它,那么它应该针对您的测试数据库运行,而不是开发。

更好的选择是destroy_all因为该版本将运行任何关联的回调。例如,如果用户有帖子,并且before_destroy如果用户被删除,您有一个回调来删除帖子。

这是有关更多信息的链接delete_all

于 2012-05-15T04:17:48.890 回答
1

delete_all将在不激活任何 Rails 回调的情况下强制从相应表中删除记录。

destroy_all将删除记录但也会调用模型回调

于 2012-05-15T13:00:11.737 回答
0

根据您的示例,它可能会删除所有用户以允许下一个 Cucumber 步骤注册新用户。ActiveRecord::Base#delete_all 方法部分说:

在不先实例化记录的情况下删除匹配条件的记录,因此不调用destroy方法也不调用回调。这是一条直接进入数据库的 SQL DELETE 语句,比 destroy_all 高效得多。

编写该测试可能有更好的方法,但其目的显然是尽可能有效地删除用户记录。

至于它是否危险,您的测试应该针对测试数据库而不是开发或生产数据库运行。由于可能会错误地配置您的测试框架以使用错误的数据库,因此您当然可以添加一个步骤或条件来测试是否Rails.env.test?为真。这是为了让内心平静而付出的相当小的代价。

于 2012-05-15T04:33:38.090 回答