2011-05-30 61 views
7

我现在开始学习Ruby和Ruby on Rails框架。我发现,在表records,我能找到一个纪录的5的ID,并通过使用下面的代码删除:为什么我不能在Rails中使用Record.all.destroy?

Record.find(5).destroy

这也在情理之中我链的方法来查找记录和摧毁它。但是,如果我要摧毁表中的所有记录,逻辑命令将以下,为all选择器选择表中的所有记录:

Record.all.destroy

而这个返回NoMethodError!我知道我可以使用Record.destroy_allRecord.delete_all来完成此任务,但是,我想知道为什么我不能使用最合理的选择,而不必查找像delete_all这样的东西。我是这个框架的新手,所以我完全有可能在这里错过了一些基本的东西。

感谢您提前提供任何答案。

+0

确实是一个很好的问题,因为我先尝试了同样的事情......您可以使用Record.all.each {| r | r.destroy}'当然,但这不像'Record.all.destroy' – 2011-05-30 16:12:27

回答

14

这是一个设计决定。 DataMapper花费了your approach。被迫明确地写destroy_all可能是乏味的,但也会阻止你做一些你真正不想要的东西(即删除表中的所有内容,如x = User; ...; x.destroy)。

+0

谢谢 - 这是我正在寻找的答案。我想这可能是防止意外大量删除记录的良好保护。 – element119 2011-05-30 16:26:35

3

我同意它会逻辑能够做到这一点。从技术上讲,Record.all返回一个集合(或代理集合),它不执行destroy方法。

1

当你有

Record.find(5) 

这将返回一个记录对象/实例代表在表中的一行数据。然后你调用由Record模型定义的对象的#destroy方法。

当你有

Record.all 

这个返回数组对象。为了让你在数组上调用#destroy,你必须修补Ruby的核心Array类来使用#destroy方法。

+0

yes and no ...因为ruby的动态特性,rails本身*可以*在数组记录中插入一个destroy动作,而不用猴子修补所有数组对象......但是这是一个设计决定,不是我想的。 – DGM 2011-05-30 18:07:40

1

避免Record.destroy_all最简单的方法是Record.all.each {|r| r.destroy}。这可能会在某种程度上满足您的API设计偏好,但应该比第一个选项慢得多。

0

其实你可以(以某种方式)。由于.all返回一个数组,而不是一个活动的记录关系,你究竟会删除什么?我不会说Record.all.destroy是合乎逻辑的 - 你在删除数组对象吗?

你可以做的一件事是映射结果数组,因为map接受一个proc(&),你可以为你的数组中的每个对象执行该proc。

Record.all.map(&:destroy) 

注意,这将触发所有对象的回调,这可能比你预期的要慢。如果你想避免触发回调,你可以映射适当的破坏性方法而不是销毁。(提示:删除)

或者,你可以只是做:

Record.destroy_all or Record.delete_all 

,你在你的问题说明。

相关问题