Reputation: 33755
I have these two scopes:
scope :posted_yesterday, -> { where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)}
scope :num_posted_yesterday, -> { posted_yesterday.count }
What I want to happen is, I would love to be able to calculate many versions of posted_yesterday
. i.e. posted_num_days_ago(n)
.
There anyway for me to create dynamic scopes to allow this, or should I just create a method on my Post
model?
Upvotes: 1
Views: 981
Reputation: 654
Do as follows:
scope :posted_on, -> (day) { where(created_at: day.beginning_of_day..(day + 1.day).beginning_of_day)}
scope :num_posted_on, -> { posted_on.count}
And suppose model name is Post then call it as follows.
Post.posted_on(Date.today - 4.days)
OR (but above is better option)
scope :posted_yesterday, -> (n) { day = (Time.now - n.days)
where(created_at: (day - 1.day).beginning_of_day..day.beginning_of_day)
}
And call:
Post.posted_yesterday(4)
Upvotes: 1
Reputation: 4147
You have 2 options here.
Creating a class method on the Post
model, as you suggested. Don't forget to define it as def self.posted_days_ago(n)
and use self
inside the method to represent the class.
Use a parameter inside a scope. It will look something like this:
scope :posted_num_days_ago, ->(n=1) {where(created_at: ((Time.now.midnight - n.days)..(Time.now.midnight - (n-1).days)))}
Notice the default value I set in this example. You may set it to whatever you need.
Upvotes: 1
Reputation: 2435
Scopes are using standard Procs known as lambdas. You should be able to by adding a parameter to you lambda. It would be something like:
scope :posted_num_days_ago -> (days_ago) {
where(
created_at: (
Time.now.midnight - (days_ago + 1).day)
)..(Time.now.midnight - days_ago.day)
)
}
This may not be exact. I haven't tested this.
But the idea is to use -> (params) { ... }
Upvotes: 1