如何使用导轨检查两个日期之间的范围 6

How to check range between two dates with rails 6

提问人:Arturo Gabriel 提问时间:8/15/2022 最后编辑:mechnicovArturo Gabriel 更新时间:8/15/2022 访问量:318

问:

您好,我有这个博客模块,我的帖子可以有 3 种状态:“no_status”、“in_draft”和“已发布”,用户可以为他的帖子设置publish_date和publish_end_date 当满足日期之间的此范围时,帖子的状态必须为“已发布”,完成后返回为“in_draft”

def post
  if self.no_status? || self.in_draft?
    if self.publish_date >=Date.today && self.publish_end <= Date.today
      self.update_attribute :status, 'published'
    end
  elsif self.published?
    if self.publish_date.past? && self.publish_end.past?
      self.update_attribute :status, 'in_draft'
    end
  end
end

管理这个问题的正确方法是什么,我的条件有很大的问题。

Ruby-on-Rails 红宝石 日期时间 Ruby-on-Rails-6

评论


答:

0赞 Sebastián Palma 8/15/2022 #1

您可以使用 Range#cover?。它基本上需要一个范围并检查日期是否在开始/结束范围内;

(10.days.ago..1.day.ago).cover?(3.days.ago)
# true

所以,就你而言;

(publish_date..publish_end).cover?(Date.today)
1赞 Konstantin Strukov 8/15/2022 #2

在第一个分支中,您的条件现在混淆了,它们应该是相反的(这就是为什么它不能按预期工作 - 您检查大于当前日期,但这是错误的 - 它必须在过去才能发布今天的帖子)。因此,如果你只是简单地“镜像”你的条件运算符,它应该可以工作 - 但是有更简洁的写法:publish_date

Date.today.between?(publish_date, publish_end)
# or
(publish_date..publish_end).cover?(Date.today)

在第 2 个分支中,检查pulish_end日期是否为过去就足够了。检查publish_date是否也是过去的,也是多余的——如果不是,你有更大的问题,只是错误的状态:)——这种基本的数据完整性最好通过模型验证来解决。

此外,嵌套的 s 在这里是绝对不必要的,它们只会使代码更难推理。if

总而言之,像下面这样的东西应该可以完成这项工作(我在这里不是讨论如何使用这种方法以及是否应该以这种方式编写 - 只是解决最初的问题)

def post
  new_status =
    if published? && publish_end.past?
      'in_draft'
    elsif Date.today.between?(publish_date, publish_end)
      'published'
    end
  
  update_attribute :status, new_status
end
1赞 mechnicov 8/15/2022 #3

你可以使用 Object#in?

def post
  if no_status? || in_draft?
    update(status: 'published') if Date.today.in?(publish_date..publish_end)
  elsif published?
    update(status: 'in_draft') if publish_date.past? && publish_end.past?
  end
end

(顺便说一句,你不是每次都用在 Ruby 中)self