ruby-on-rails – 我该怎么做? Model.where(“created_at> =#{Time.now – 5.days}”)

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 我该怎么做? Model.where(“created_at> =#{Time.now – 5.days}”)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这一直在欺骗我一段时间…

如何在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
)

使用(well)命名的占位符为您提供了您认为字符串插值提供的可读性和位置独立性,但很好地回避了引用,时区和格式问题,您可以对字符串进行插值.

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

>引用和转义.
>时间戳格式
>也许是时区.

ActiveRecord将为您处理所有这些废话.

不要尝试引用自己的话,用司机的引用方法.您可以访问connection.quote以正确引用字符串.

任何数据库都将知道如何处理ISO 8601 timestamps,并有一个方便的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时间戳,您应该安全地用简单的单引号代替connection.quote调用

Model.where("created_at >= '#{(Time.now - 5.days).utc.iso8601}' " + \
         "OR updated_at >= '#{(Time.now - 3.days).utc.iso8601}'")

但你仍然会有很多的噪音和丑陋,你会发展不好的习惯.

在1999年,我们不像PHP程序员那样派对,所以不要在sql中使用字符串插值来使用命名占位符,来放弃虚假的懒惰.

猜你在找的Ruby相关文章