Ruby on rails 我该怎么做?Model.where(“created”u at>;={Time.now-5.days})

Ruby on rails 我该怎么做?Model.where(“created”u at>;={Time.now-5.days}),ruby-on-rails,activerecord,rails-activerecord,Ruby On Rails,Activerecord,Rails Activerecord,这困扰了我一段时间 如何在Rails ActiveRecord查询中插入datetime # Works, but supeh ugleh: Model.where("created_at >= ?", Time.now - 5.days) # How do I do this? Model.where("created_at >= #{Time.now - 5.days}") # As is, it produces the following error message: #

这困扰了我一段时间

如何在Rails ActiveRecord查询中插入
datetime

# Works, but supeh ugleh:
Model.where("created_at >= ?", Time.now - 5.days)

# How do I do this?
Model.where("created_at >= #{Time.now - 5.days}")
# As is, it produces the following error message:
# ActiveRecord::StatementInvalid: PG::Error: ERROR:  syntax error at or near ...
我关心代码可读性的原因是:

# I like this better:
Model.where("created_at >= #{Time.now - 5.days} OR" + \
            "updated_at >= #{Time.now - 3.days}")

# than this:
Model.where("created_at >= ? OR updated_at >= ?", Time.now - 5.days, Time.now - 3.days)

我建议不要使用字符串插值,因为有很多尖锐的边缘,你可能会在鱼钩桶里玩苹果。你应该这样做:

Model.where(
    'created_at >= :five_days_ago or updated_at >= :three_days_ago',
    :five_days_ago  => Time.now - 5.days,
    :three_days_ago => Time.now - 3.days
)
使用(良好)命名的占位符可以提供可读性和位置独立性,这是您认为字符串插值提供的,但很好地避开了字符串插值强加给您的引号、时区和格式问题

但是如何安全地使用字符串插值呢?有几件事你必须自己处理:

  • 引用和逃避
  • 时间戳格式
  • 也许还有时区
  • ActiveRecord将为您处理所有这些废话

    不要试图自己引用,使用驱动程序的引用方法。您将有权访问
    connection.quote
    以正确引用字符串

    任何数据库都知道如何处理,并且有一种方便的
    iso8601
    方法。ISO 8601还方便地包括时区,数据库应该能够解析该时区(但如果不能解析,则您必须手动使用
    .UTC
    )将时间转换为UTC)

    因此,为了安全起见:

    Model.where("created_at >= #{connection.quote((Time.now - 5.days).utc.iso8601)} " + \
             "OR updated_at >= #{connection.quote((Time.now - 3.days).utc.iso8601)}")
    
    现在不太漂亮了,是吗?使用ISO 8601时间戳,您应该可以安全地用简单的单引号替换
    连接。quote
    调用:

    Model.where("created_at >= '#{(Time.now - 5.days).utc.iso8601}' " + \
             "OR updated_at >= '#{(Time.now - 3.days).utc.iso8601}'")
    
    但是你仍然有很多噪音和丑陋,你会养成坏习惯


    我们不像1999年的PHP程序员那样参加聚会,所以不要因为在SQL中使用字符串插值而屈服于虚假的懒惰,使用命名占位符。

    老问题,但我最喜欢的方法是:

    Model.where(created_at: 5.days.ago..Time.current)
    
    更漂亮、更可读

    另外,一些主动支持助手方法可以获得一些常用范围,
    时间#全天
    时间#全周
    时间#全季
    时间#全年
    ,因此您可以执行以下操作:

    Model.where(created_at: Time.current.all_week)
    

    女士们,先生们,这就是为什么mu在撰写本文时拥有74.2k代表。我只能投一次赞成票,但我真的很欣赏你的回答的清晰和彻底。“在鱼钩桶里跳苹果”史诗