Ruby on rails 正确使用“rescue”(或“try”)
当我有一个可能存在或不存在的模型属性,并且我需要在它之后链接一些方法时,我会添加Ruby on rails 正确使用“rescue”(或“try”),ruby-on-rails,ruby,Ruby On Rails,Ruby,当我有一个可能存在或不存在的模型属性,并且我需要在它之后链接一些方法时,我会添加present?。例如: Car.last.passengers.present? and Car.last.passengers.each do { |passenger| puts passenger.name } 在这种情况下,使用rescue是否更好?比如说 Car.last.passengers.each { |passenger| puts passenger.name } rescue "No
present?
。例如:
Car.last.passengers.present? and
Car.last.passengers.each do { |passenger| puts passenger.name }
在这种情况下,使用rescue
是否更好?比如说
Car.last.passengers.each { |passenger| puts passenger.name } rescue "No passengers in the car!"
编辑:
谢谢你的回复。我应该问一个更一般的问题:“处理一个潜在的<代码> NIL<代码>的最佳方法是在一系列方法的中间结果?”
为了清楚起见,让我把我的例子说得更一般一些。如果我打电话:
Car.last.driver.pocket_contents
但是
Car
的最后一个实例没有driver
,我会在nil
上调用pocket\u contents
。根据下面的一位评论者,我是否应该使用try
,如果是这样,您能告诉我在这种情况下如何简洁地使用它吗?您不想挽救应该发生的异常。如果预期属性可能不存在或对象可能为零,则您可能希望使用try
或try代码>方法
如果对象不是nil,则尝试调用方法/属性。如果try
方法在链的某个地方无法完成,它将悄悄地计算为nil。试试看如果试图调用非nil对象上不存在的方法,code>方法将引发一个NoMethodError
您不想挽救应该发生的异常。如果预期属性可能不存在或对象可能为零,则您可能希望使用try
或try代码>方法
如果对象不是nil,则尝试调用方法/属性。如果try
方法在链的某个地方无法完成,它将悄悄地计算为nil。试试看如果试图调用非nil对象上不存在的方法,code>方法将引发一个NoMethodError
这里绝对没有理由使用rescue
。使用异常处理机制进行流控制被广泛认为是对异常的滥用,通常被认为是一种不好的做法
也可能没有理由使用x.present?&&x、 每个
,就像(如果这是一个ActiveRecord关联)它永远不会返回错误的“不存在”值一样。它将始终返回一个类似数组的对象,表示0个或多个项目,您可以安全地在每个项目上调用。如果这不是ActiveRecord关联,则应更改代码以遵循此约定,并返回空数组,而不是nil
在一般情况下(假设可用),您可以使用try
。假设乘客
是一种可能返回nil
的方法,则您的.present?
检查应该是try
调用:
Car.last.passengers.try(:each) { ... }
这可以链接到艺术的长度;这两者是等效的:
a&&a.b&&a.b.c
- 试一下(:b)。试一下(:c)
请注意,如果您的方法不返回nil
,而是返回一个值,那么这将不起作用
如果try
不可用,那么您当前的解决方案是一种广泛使用的做法,除了您-这些在Ruby中不是等价的运算符
Car.last.passengers && Car.last.passengers.each { ... }
如果要保存字符,可以使用|
而不是&&
来提供默认值,然后再使用当前正在考虑的脏解救
技巧:
(Car.last.passengers || []).each { ... }
如果这是一个ActiveRecord关联,那么有几种惯用的Rails解决方案,其中最好的是将“put”(我假设实际上是呈现一系列HTML元素)移动到它自己的部分,称为\u passenger.HTML.erb
。然后,可以渲染整个集合:
= render Car.last.passengers
如果要以不同的方式处理呈现空集,则在呈现空集合时,应依赖render
返回false
的行为:
= render Car.last.passengers || render 'no_cars'
这样,用于向用户显示“没有乘客”消息的标记将存储在\u no\u cars.html.erb
部分中,并用一行清晰地呈现。这里绝对没有理由使用rescue
。使用异常处理机制进行流控制被广泛认为是对异常的滥用,通常被认为是一种不好的做法
也可能没有理由使用x.present?&&x、 每个
,就像(如果这是一个ActiveRecord关联)它永远不会返回错误的“不存在”值一样。它将始终返回一个类似数组的对象,表示0个或多个项目,您可以安全地在每个项目上调用。如果这不是ActiveRecord关联,则应更改代码以遵循此约定,并返回空数组,而不是nil
在一般情况下(假设可用),您可以使用try
。假设乘客
是一种可能返回nil
的方法,则您的.present?
检查应该是try
调用:
Car.last.passengers.try(:each) { ... }
这可以链接到艺术的长度;这两者是等效的:
a&&a.b&&a.b.c
- 试一下(:b)。试一下(:c)
请注意,如果您的方法不返回nil
,而是返回一个值,那么这将不起作用
如果try
不可用,那么您当前的解决方案是一种广泛使用的做法,除了您-这些在Ruby中不是等价的运算符
Car.last.passengers && Car.last.passengers.each { ... }
如果要保存字符,可以使用|
而不是&&
来提供默认值,然后再使用当前正在考虑的脏解救
技巧:
(Car.last.passengers || []).each { ... }
如果这是一个ActiveRecord关联,那么有几种惯用的Rails解决方案,其中最好的是移动“put”(我假设实际上是呈现一系列HTML元素)