我正在使用字段通过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
即。它只是在每次运行时记录“销毁...”行。
答案 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}}