【问题标题】:A lambda expression in a rails validation statementrails 验证语句中的 lambda 表达式
【发布时间】:2015-08-03 14:32:02
【问题描述】:

我正在使用timeliness gem 进行时间和日期验证。

我的事件模型有一个存储“11:15”之类的字符串的时间字段、一个存储日期对象的start_dateend_date

我想要以下验证行为:

如果用户尝试在一年中的当天创建一个事件(所以start_date == Date.today),并且时间是过去的(所以如果创建事件时是 15:30 并且用户输入了 11 :30),那么验证应该会失败。即,我们只希望在日期是今天或将来以及时间的位置创建事件,如果日期是今天,在未来强>.

我正在为此尝试以下验证:

validates :time, :presence => true,
    :timeliness => { :type => :time, :on_or_after => lambda { if(:start_date == Date.today && :day_of_week.downcase == Date.today.strftime("%A").downcase) then return Time.new(:time.to_s).in_time_zone(:timezone)>Time.now.in_time_zone(:timezone) else return true end } }

但是它的行为不正确。即我能够创建一个 start_date 为 03/08/2015 且时间为 09:00 的事件,尽管它是 03/08/2015 的 15:31!请帮忙!

【问题讨论】:

  • 在我看来,你有一个很大的 lambda 表达式,最好定义一个方法而不是 lambda。对我来说很难读。这将变为validates :time, :presence => true, :timeliness => correct_time

标签: ruby-on-rails ruby validation ruby-on-rails-4 time


【解决方案1】:

您的 lambda 没有多大意义,因为您到处都在使用符号 - :start_date == Date.today 将永远是 false。验证中 lambdas 的值是它们传递了您的 Event 实例,因此您可以引用 event.start_date。我同意 cmets 中的@arthur.karganyan 的观点,即如果您需要这么复杂的东西,作为一种方法使用起来会更容易。

但是,您也使这比您需要的复杂得多。看起来您将 start_datetime 作为单独的属性,这很难使用,因为它们往往会相互依赖。我建议将它们改为单个 start_time 属性,然后您可以像这样使用 validates_timeliness

validates_datetime :start_time, on_or_after: -> { Time.now }

如果您必须有单独的属性,您的验证可能如下所示:

validates_date :start_date, on_or_after: -> { Date.today }
validates_time :time, on_or_after: lambda { |event| Time.now if event.start_date.today? }

这会验证日期是今天还是将来,如果是今天,还要检查时间。当on_or_after lambda 评估为nil 时,validates_timeliness 似乎接受任何time

【讨论】:

  • 我试过:验证 :time, :presence => true, :timeliness => { :type => :time, :on_or_after => { Time.now if start_date.today?但是这导致了语法 - 所以我在块之前添加了 lambda,这修复了错误但验证仍然无法捕获小于当前时间的时间
  • 注意你的语法。您的 :on_or_after => { Time.now... } 正在尝试将块设置为哈希值。注意=> (hash rocket) 和-> (lambda literal) 之间的区别
  • 即使完全按照您的方式进行操作也无法触发验证错误?
  • 如果我尝试: validates_time :time, on_or_after: -> { Time.now if start_date.today?我做了一个“11:30”的时间和一个今天的 start_date 它不会失败验证。
  • @RenegadeAndy 抱歉,我在 self 上引用了一些东西,而实际上验证 lambda 接收实例作为参数。用我实际运行的代码更新了答案:)
猜你喜欢
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 2019-09-19
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多