ActiveRecord破坏 - 也不例外

时间:2013-12-10 20:27:56

标签: exception activerecord

我正在使用字段通过ActiveRecord进行destroy。但是,具有该字段值的数据库中的记录不存在。所以,使用pry进行这一点调试:

[1] pry(main)> fieldvalue
=> "17785"
[2] pry(main)> person =  Person.where(:fieldname => fieldvalue.to_i)
=> []
[3] pry(main)> person
=> []
[4] pry(main)> person.destroy_all
=> []

...为什么不在第4步引发例外?

原始的代码位同样无声地引发异常:

  

开始       Person.where(:fieldname => fieldvalue.to_i).destroy_all

rescue ActiveRecord::RecordNotFound => exception
  @logger.info("ActiveRecord::RecordNotFound exception raised. Details: #{exception}")   
rescue Exception => exception
  @logger.info("Unknown exception raised. Details: #{exception}")
else
  @logger.info("Destroying person with field value: #{fieldvalue}")
end

即。它只是在每次运行时记录“销毁...”行。

1 个答案:

答案 0 :(得分:2)

destroy_all在空集([])上执行时不会引发异常,因为该方法根据the documentation

  

通过实例化每条记录并调用其destroy方法来销毁记录匹配条件。

因为您的where查询返回一个空集,所以没有要实例化的记录 - destroy 从未实际在任何事情上执行,因此没有抛出异常

将此与假设情况进行对比,其中返回一个集合 - 由于某些不太可能的原因 - 包含nil个对象。该集可能看起来像这样

people = Person.where("created_at < ?", Time.now)
#=> [#<Person id:1>, nil, #<Person id:2>] # for demonstration only; would not actually happen

people.destroy_all
#=> NoMethodError: undefined method `destroy' for nil:NilClass

NoMethodError会在destroy_all的第二个迭代上抛出,因为destroy会在nil上执行,destroy没有where方法。

另一个想法:您可能会将where ActiveRecord方法与find方法混为一谈。 ActiveRecord::Relation返回一个find对象,它有效地作为与传递条件匹配的对象数组运行。相反,find会返回第一个对象本身 _ ,它与传递的条件相匹配。在上面的真实示例中,如果您要从查询中返回单个对象,使用where而不是people = Person.where(:fieldname => fieldvalue.to_i) # returns a collection of all objects matching the condition people.class #=> ActiveRecord::Relation person = Person.find(:fieldname => fieldvalue.to_i) # returns the FIRST object matching the condition person.class #=> Person 更有意义:< / p>

{{1}}