如何创建动态范围,如果可能,我可以传入对象?

时间:2015-03-07 05:44:02

标签: ruby-on-rails ruby-on-rails-4

我有这两个范围:

  scope :posted_yesterday, -> { where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)}
  scope :num_posted_yesterday, -> { posted_yesterday.count }  

我想要发生的是,我希望能够计算posted_yesterday的许多版本。即posted_num_days_ago(n)

无论如何我要创建动态范围来允许这个,或者我应该只在我的Post模型上创建一个方法?

3 个答案:

答案 0 :(得分:1)

范围使用称为lambdas的标准Proc。您应该可以通过向lambda添加参数。它会是这样的:

scope :posted_num_days_ago -> (days_ago) {
  where(
    created_at: (
      Time.now.midnight - (days_ago + 1).day)
    )..(Time.now.midnight - days_ago.day)
  )
}

这可能不准确。我没有测试过这个。

但想法是使用-> (params) { ... }

答案 1 :(得分:1)

这里有2个选项。

  1. 按照建议在Post模型上创建一个类方法。不要忘记将其定义为def self.posted_days_ago(n)并在方法中使用self来表示该类。

  2. 在范围内使用参数。它看起来像这样:

    scope :posted_num_days_ago, ->(n=1) {where(created_at: ((Time.now.midnight - n.days)..(Time.now.midnight - (n-1).days)))}
    
  3. 注意我在此示例中设置的默认值。您可以将其设置为您需要的任何内容。

答案 2 :(得分:1)

请执行以下操作:

scope :posted_on, -> (day) { where(created_at: day.beginning_of_day..(day + 1.day).beginning_of_day)}
scope :num_posted_on, -> { posted_on.count}

假设模型名称为Post,则按如下方式调用。

Post.posted_on(Date.today - 4.days)

OR(但上面是更好的选择)

scope :posted_yesterday, -> (n) { day  = (Time.now - n.days)
   where(created_at: (day - 1.day).beginning_of_day..day.beginning_of_day)
}

并致电:

Post.posted_yesterday(4)