1

我有一段代码女巫看起来像这样:

Post.all.reject {|p| p.created_at.beginning_of_month != params[:date].to_date}

有没有一种方法可以使用 where 方法编写相同的代码并且不获取所有元素?

4

3 回答 3

4

如果你想使用where,我会去:

# x-month being a date from your desired month.
# .. defines the range between the beginning and the end
Post.where(:created_at => x-month.beginning_of_month..x-month.end_of_month)
于 2013-11-04T13:54:35.057 回答
3

AFAIK,没有与数据库无关的解决方案,因为您需要从日期中提取月份。因此,在原始 SQL 中,您将拥有:

date = params[:date].to_date
Post.where("MONTH(created_at) != ? AND YEAR(created_at) = ?", [date.month, date.year]) 

现在可以通过规范化作弊,以便使用与 db 无关的解决方案。只需在模型中添加一些created_at_monthcreated_at_year列,以及此回调:

after_create :denormalize_created_at
def denormalize_created_at
  assign_attributes created_at_month: created_at.month, 
                    created_at_year:  created_at.year
  save validate: false 
end

现在你可以这样做:

导轨 < 4 :

date = params[:date].to_date
Post
  .where(Post.arel_table[:created_at_month].not_eq date.month)
  .where(created_at_year: date.year)

导轨 4+:

date = params[:date].to_date
Post.not(created_at_month: date.month).where(created_at_year: date.year)
于 2013-11-04T13:56:10.923 回答
3

mysql 具有MONTH获取日期时间列的月份的功能。

 Post.where("MONTH(created_at) != ?", params[:date].to_date.month)
于 2013-11-04T13:57:19.307 回答