我有一段看起来像这样的代码:
Post.all.reject {|p| p.created_at.beginning_of_month != params[:date].to_date}
是否有方法使用where方法编写相同的代码并且不获取所有元素?
答案 0 :(得分: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)
答案 1 :(得分:3)
AFAIK,没有与此数据库无关的解决方案,因为您需要从日期中提取月份。因此,在原始SQL中,您将拥有:
date = params[:date].to_date
Post.where("MONTH(created_at) != ? AND YEAR(created_at) = ?", [date.month, date.year])
现在可以通过规范化来作弊,以便使用与数据库无关的解决方案。
只需在模型中添加一些created_at_month
和created_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
现在你可以做到:
Rails< 4:
date = params[:date].to_date
Post
.where(Post.arel_table[:created_at_month].not_eq date.month)
.where(created_at_year: date.year)
Rails 4+:
date = params[:date].to_date
Post.not(created_at_month: date.month).where(created_at_year: date.year)
答案 2 :(得分:3)
mysql有一个MONTH
函数来获取datetime列的月份。
Post.where("MONTH(created_at) != ?", params[:date].to_date.month)