the*_*ole 18 activerecord ruby-on-rails rails-activerecord
这一直困扰我一段时间......
我怎样才能串插一个datetime在Rails的ActiveRecord的查询?
# 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 ...
Run Code Online (Sandbox Code Playgroud)
我关心的原因是代码可读性:
# 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)
Run Code Online (Sandbox Code Playgroud)
mu *_*ort 59
我建议不要使用字符串插值,有许多锋利的边缘,你可能会有更多的乐趣在一桶鱼钩中摇摆苹果.你应该这样做:
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
)
Run Code Online (Sandbox Code Playgroud)
使用(好)命名占位符为您提供了字符串插值所提供的可读性和位置独立性,但很好地回避了字符串插值对您的引用,时区和格式问题.
但是你如何安全地使用字符串插值?你必须自己处理一些事情:
ActiveRecord将为您处理所有这些废话.
不要尝试自己做引用,使用驱动程序的引用方法.您可以访问connection.quote正确引用字符串.
任何数据库都知道如何处理ISO 8601时间戳,并且有一个方便的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)}")
Run Code Online (Sandbox Code Playgroud)
现在不是很漂亮吗?使用ISO 8601时间戳,您应该connection.quote使用简单的单引号来安全地替换呼叫:
Model.where("created_at >= '#{(Time.now - 5.days).utc.iso8601}' " + \
"OR updated_at >= '#{(Time.now - 3.days).utc.iso8601}'")
Run Code Online (Sandbox Code Playgroud)
但你仍然有很多噪音和丑陋,你会养成坏习惯.
我们不会像1999年的PHP程序员一样参与派对,所以不要在SQL中使用字符串插值来放弃虚假的懒惰,使用命名的占位符.
Mik*_*ell 57
老问题,但我最喜欢的方法是:
Model.where(created_at: 5.days.ago..Time.current)
Run Code Online (Sandbox Code Playgroud)
更漂亮,更可读.
此外,Rails的3.2中引入了一些积极的支持辅助方法得到一些常见的一些范围,Time#all_day,Time#all_week,Time#all_quarter和Time#all_year,所以你可以为实例做:
Model.where(created_at: Time.current.all_week)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26569 次 |
| 最近记录: |