如何在Ruby中查询方法的结果(rails)

时间:2014-12-21 12:16:36

标签: ruby-on-rails ruby activerecord

我正在努力解决某个特定功能。

在我的用户模型中,我有一种方法可以根据当前日期减去第一个订单日期来计算出他们的年龄。

我希望能够找到超过X天的所有用户。我可以通过查询名为“状态”的列来查找活动用户“活动”#39;用户。但我不确定如何查询年龄方法的结果以查找早于X的用户。

有没有人有任何想法?

非常感谢和节日的问候。

**编辑

在postgresql中我会写;

WITH 
firstbill as (
SELECT 
  DISTINCT(user_id) as customer,
  DATE(MIN(billed_at)) as first_order
FROM orders
WHERE state = 'shipped'
GROUP BY 1
ORDER BY 1)

SELECT count*
FROM 
(SELECT *, (current_date - first_order) as age
FROM firstbill
JOIN users on users.id = customer) as t2
WHERE age >= 21

我尝试过使用User.find_by_sql ["上面的查询"]但是返回的数组不是activerecord关系,这使得任何进一步的连接变得更难

2 个答案:

答案 0 :(得分:2)

您无法真正查询方法的返回值。因为要这样做,您需要加载所有用户,然后在每个用户上调用该方法,例如User.all.select(&:your_method?)。如果你有很多用户,那将会很慢。

但是对于您的特定示例,您可以编写类似这样的内容,让数据库返回正确的用户(假设您的用户有first_order列):

User.where('first_order <= ?', 90.days.ago)

User.where('first_order <= ?', 1.month.ago)

我认为以下启动应该返回与Postgresql示例相同的用户:

User.
  select('users.*, MIN(DATE(orders.billed_at)) AS first_order_on').
  joins('orders ON orders.user_id = users.id').     # just `(:orders)` with `has_many :order` on User 
  where('orders.state = ?', 'shipped').
  group('users.id').
  having('first_order_on <= ?', 21.days.ago.to_date)

答案 1 :(得分:0)

使用

解决
scope :acquired, User.joins(:orders).where("orders.state = ?", "shipped")
scope :older_than_age, ->(age) {
acquired.group("users.id").having("(current_date - date(min(orders.shipped_at))) >= ?", age)
}