【问题标题】:Rails 3.2 - ActiveRecord `where` query with method called on attributeRails 3.2 - ActiveRecord `where` 查询与在属性上调用的方法
【发布时间】:2014-11-05 18:36:58
【问题描述】:

在控制台中,我可以像这样查询我的Job 表:jobs = Job.where("created_at <= ?", Time.now)

我想获得今年创造的工作。如果我得到一份单独的工作,我可以使用job.created_at.year,但如果我尝试使用jobs = Job.where("created_at.year = ?", 2014),我会收到以下错误:

SQLite3::SQLException: no such column: created_at.year

我想我理解问题在于我正在尝试将 Ruby 混合到 SQL 查询中,但我不确定如何解决它。理解这一点将帮助我创建更强大的 ActiveRecord 查询。

编辑我发现我可以像这样使用.map 来做到这一点:Job.all.map { |j| j if j.created_at.year == 2014 }。如果我想收集需要在属性上调用方法的作业集合,这是最好的方法吗?

【问题讨论】:

    标签: mysql ruby-on-rails ruby database activerecord


    【解决方案1】:

    试试这个:

    Job.where(:created_at => Time.now.beginning_of_year..Time.now.end_of_year)
    

    由于调用 Time.now 可能会给出两个不同的年份(12 月 31 日午夜之前和之后),因此最好先为当前时间创建一个变量,然后再将其用于查询:

    current_time = Time.now
    Job.where(:created_at => current_time.beginning_of_year..current_time.end_of_year)
    

    【讨论】:

    • 或者更简单地使用 MySQL 的原生 YEAR() 函数:"YEAR(created_at) = ?" 将接受 Time.now.year
    • @MichaelBerkowski:哦,有趣。感谢您的投入。 :)
    • @MichaelBerkowski 除了时间和日期处理函数往往是特定于数据库的,而 ActiveRecord 太笨,无法涵盖这个可移植性问题;请注意问题中的 SQLite 异常。当然,尝试通过 ORM 实现数据库可移植性通常是在浪费时间,除非您打算以艰难的方式(即您自己)或在 baby-talk-SQL 中与数据库交谈,所以这很少是真正的问题.
    • @muistooshort :在阅读了您的评论后,我也觉得像 ActiveRecord 这样的 ORM 对产生这种复杂查询的方法的实现很差/没有实现。见鬼,甚至NOT 在 Rails 4 中被引入,并且想知道为什么他们花了这么长时间才制作出一种方法来产生如此有用的查询。 ActiveRecord 确实提供了数据库的可移植性,但它只适合进行普通的 where 和 join 查询,否则必须编写原始 SQL 才能在现实生活场景中完成工作,这再次扼杀了首先拥有 ORM 的好处。你已经很好地表达了想法。谢谢。
    • 这适用于我的示例案例,但我仍然想知道如何在.where 查询中调用属性上的方法的更一般的问题。另一个例子是,如果我需要使用存储为字符串的时间属性进行时间比较。比如我不能Job.where("string_time.to_time > ?", Time.now)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    相关资源
    最近更新 更多