【问题标题】:How to get records created at the current month?如何获取当月创建的记录?
【发布时间】:2021-03-22 20:34:21
【问题描述】:

我有一个候选人有_many 票。

我正在尝试获取当月创建的候选人的选票?

@candidate.votes.from_this_month

scope :from_this_month, where("created_at > ? AND created_at < ?", Time.now.beginning_of_month, Time.now.end_of_month)

这给了我一个 PG 错误: PG::Error: ERROR: 列引用“created_at”不明确

如果我尝试

scope :from_this_month, where("vote.created_at > ? AND vote.created_at < ?", Time.now.beginning_of_month, Time.now.end_of_month)

我收到以下错误

PG::Error: ERROR:  missing FROM-clause entry for table "vote"

【问题讨论】:

  • 用 S 试试votes
  • 与问题无关,但Time.zone.now 优于Time.now

标签: ruby-on-rails ruby postgresql


【解决方案1】:

正确的范围

scope :from_this_month, lambda {where("votes.created_at > ? AND votes.created_at < ?", Time.now.beginning_of_month, Time.now.end_of_month)}

这是因为在 Rails 中,模型名称是单数的(即 Vote),而通过对流创建的表是纯的(例如 votes

编辑

这可以用lambda {where(created_at: Time.now.beginning_of_month..(Time.now.end_of_month))}写得更简单,由于下面的cmets给出的原因,我们需要使用lambda。

感谢 BroiSatse 提醒 :D

【讨论】:

  • 这可以用where(created_at: Time.now.beginning_of_month..(Time.now.end_of_month))写得更简单
  • 这将无法正常工作,因为 Time.now 将在加载类时评估,而不是在调用方法时评估。它应该包含在 lambda
  • Thanx bridiver 我现在已经更正了答案。没想到这个问题
【解决方案2】:

您还需要将 where 包含在 lamda 中。

scope :from_this_month, lambda { where("votes.created_at > ? AND votes.created_at < ?", Time.now.beginning_of_month, Time.now.end_of_month) }

否则它可能看起来有效并且您的测试将全部通过,但如果您的应用程序运行超过一个月,您将开始得到不正确的结果,因为 Time.now 是在类加载时评估的,而不是在调用方法时.

【讨论】:

    【解决方案3】:
      scope :this_month, -> { where(created_at: Time.zone.now.beginning_of_month..Time.zone.now.end_of_month) }
    

    你可以调用作用域:

    Model.this_month

    【讨论】:

      【解决方案4】:

      你可以使用ActiveRecord Association Extension:

      #app/models/Candidate.rb
      Class Candidate < ActiveRecord::Base
         has_many :votes do
             def from_this_month
                 where("created_at > ? AND created_at < ?", Time.now.beginning_of_month, Time.now.end_of_month)
             end
         end
      end
      

      这应该允许您调用@candidate.votes.from_this_month 以返回所需的条件数据

      【讨论】:

        【解决方案5】:

        从 Rails 5 开始,您有了更简洁的语法。在您的投票模型上添加一个范围 this_month

         scope :this_month, -> { where(created_at: Date.today.all_month) }
        

        您现在可以查询@candidates.votes.this_month

        【讨论】:

          猜你喜欢
          • 2014-02-12
          • 1970-01-01
          • 2022-01-25
          • 2023-02-21
          • 2014-12-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多