3

我想尝试将参数中的日期转换为日期格式,如果不能,那么我想将它分配给今天一年的日期。

这是我尝试过的。

valid_until = params[:valid_until].try(:to_date) || Date.today.next_year

这个try方法很酷,因为如果:valid_until日期为 nil,它只会返回 nil。我发现,如果有人有一个无效日期,如“4790224374”,那么它将返回一个ArgumentError无效日期。该:valid_until日期仍将针对to_date

我猜想通过救援来解决这个问题似乎是唯一的答案,只是想知道在明年将其设置为默认值之前,是否有更聪明的方法来尝试解决 nils 和无效日期错误。

编辑:

您可以在此处阅读有关 Try 的信息

您可以在此处阅读有关 to_date 的信息

4

2 回答 2

2

您在滥用 Object.try。如果对象上不存在方法,则此方法将静默失败。在这种情况下,该方法存在(因此被调用)并且该方法失败。

这并不是要替换 try/rescue 块。下面是一个可能的实现。

def expiration_date(a_string)
  Date.parse(a_string)
rescue
  Date.today.next_year
end

valid_until = expiration_date(params[:valid_until])
于 2014-09-30T15:37:48.737 回答
1

除非它是某种代码高尔夫,否则我不会试图在一个班轮中尽可能多地挤入逻辑。此外,您可能希望控制器尽可能精简。为什么不使用一些理智的 OO 直觉来告诉您:“如果我无法弄清楚这里的逻辑,也许我应该将其提取到单独的方法或类中”?Fi

# app/services/expirer.rb
class AccountExpirer
  def self.expiration_date(user_input)
    return Date.today.next_year unless user_input.present?
    begin
      Date.parse(user_input)
    rescue ArgumentError
      Date.today.next_year
    end
  end
end

# some controller
valid_until = AccountExpirer.expiration_date(params[:valid_until])

但是如果你需要告诉用户他输入了无效数据,我不会在这里停下来。ActiveModel::Model您可以使用( http://api.rubyonrails.org/classes/ActiveModel/Model.html )扩展您的类,这将允许您编写适当的验证,并在您的表单中使用它(就像 AR 模型一样)。

于 2014-09-30T15:52:23.070 回答