我正在尝试构建一种方法,让我通过一个月,然后可以动态查询上个月。
total_churn(month)
last_month = month - 1
companies = Company.where("created_at BETWEEN '#{last_month}' AND '#{month}')
return companies.count
end
如何以可以使用 ruby on rails 动态确定上个月的方式传递方法“月”?谢谢
我正在尝试构建一种方法,让我通过一个月,然后可以动态查询上个月。
total_churn(month)
last_month = month - 1
companies = Company.where("created_at BETWEEN '#{last_month}' AND '#{month}')
return companies.count
end
如何以可以使用 ruby on rails 动态确定上个月的方式传递方法“月”?谢谢
My suggestion: accept a date rather than a month.
total_churn(date)
month_previous = date - 1.month
companies = Company.where("created_at BETWEEN ? AND ?, '#{month_previous}', '#{date}')
return companies.count
end
Current month:
Time.now.month
Date.today.month
Time or day one month ago:
(Time.now - 1.month).month
(Date.today - 1.month).month
...also equivalent to:
Time.now.month - 1
Date.today.month - 1
Previous month for any given date:
@date - 1.month
我会亲自建立您的方法来接受日期而不仅仅是一个月数。只要 created_at 字段存储日期,您就需要为查询提供两个日期才能运行,即使这些日期是第一个。
Rails 有一些有用的时间助手来为您的查询创建上限和下限。(beginning_of_month
并且end_of_month
在Time 类中)
这种方法也可以用问号而不是字符串插值来正确转义,这对 SQL 注入攻击是开放的。
def total_churn(month)
companies = Company.where('created_at BETWEEN ? and ?',(Time.now - 1.month).beginning_of_month,(Time.now - 1.month).end_of_month)
companies.count
end
我还要说,这只适用于最近一年。如果您希望能够查询更早的数据,您可能需要添加一个年份参数或简单地传入一个日期并让它使用它来代替Time.now
.
# with separate year and month params
def total_churn(month, year)
date = DateTime.parse("#{year}/#{month}/01")
companies = Company.where('created_at BETWEEN ? and ?',(date - 1.month).beginning_of_month,(date - 1.month).end_of_month)
companies.count
end
# with a random date input
def total_churn(date_in_month)
companies = Company.where('created_at BETWEEN ? and ?',(date_in_month - 1.month).beginning_of_month,(date_in_month - 1.month).end_of_month)
companies.count
end
您至少需要 2 个参数来完成此操作,一个用于月份,一个用于年份。这是确定您想要的月份所必需的。
def total_churn(year, month)
date = Date.new year, month
one_month_ago = date - 1.month
...
但是,如果您已经有一个日期对象,那么您可以使用 sscirrus 的答案。如果日期在字符串中,您可能需要先解析它(就像在您的评论中一样)
def total_churn(date_string)
date = Date.parse(date_string)
one_month_ago = date - 1.month
...
>> date_string = '2012-09-01 00:00:00.000000'
>> total_churn date_string