Rails where查询中的自定义模型方法

Rails custom model method in where query

在我的 rails 应用程序中,我在 Kid 模型中定义了一个基于 Kids 数据库字段的计算。方法如下:

def flip_date 
  self.dob.advance(months: 10) 
end

我想在我的控制器中使用它,因为我有一个定义如下内容的方法:

new_kids = Kid.where(discharge_date: nil).where('flip_date > ?', Date.current.advance(year: 1).beginning_of_year)

但是我不断收到以下错误:

SQLite3::SQLException: no such column: flip_date: SELECT "kids".* FROM "kids" WHERE "kids"."discharge_date" IS NULL AND (flip_date < '2017-01-01')

关于如何使这项工作有任何想法吗?感谢所有帮助!

如果您真的想使用模型方法,请查看 http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/select

针对您的情况:

new_kids = Kid.where(discharge_date: nil).select{|k| k.flip_date > Date.current.advance(year: 1).beginning_of_year}

但是 select 方法在返回最终结果之前获取内存中的每个对象。因此,我建议使用普通的 where 子句,而不是 flip_date 考虑 dob(这是数据库中的一列)。

像这样

new_kids = Kid.where(discharge_date: nil).where('dob > ?', <date criteria>)

如果您同意 return 作为数组,select 方法 (http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/select) 效果很好。

我仍在寻找一种方法来使用 ActiveRecord_Relation return。

如果其他人知道如何做到这一点,如果您能分享,我们将不胜感激。

此示例不会响应您的特定代码,但在某种程度上它可以帮助其他有类似问题的人,这里是一个非常简单的示例,说明 .select 如何非常方便:

@expired_memberships = User.select{|u| u.membership_expired_yesterday?}

在该示例中,您循环遍历了所有用户并根据您在 User 模型 (membership_expired_yesterday?) 上定义的自定义方法过滤了它们。现在您可以像邮件程序中的这个示例一样轻松地对该集合进行操作:

@expirations.each do |user|
  MembershipExpirationMailer.with(user: user).first_reminder.deliver_now
end