# Testing time-dependent named\_scopes

**URL:** <https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544>\
**Category:** Rails\
**Created:** [October 22, 2008, 5:52pm UTC](https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544 "2008-10-22T17:52:27Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![sven](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e47c2d/32.png) [@sven](https://www.ruby-forum.com/u/sven)\
**Post date:** [October 22, 2008, 5:52pm UTC](https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544/1 "2008-10-22T17:52:27Z")

</div>

Suppose I have the following model, which defines a named\_scope that  
filters out some instances based on the current time:

class Post \< ActiveRecord::Base  
named\_scope :current, lambda {  
{ :conditions =\> [‘do\_not\_show\_before \< ?’, Time.now] }  
}  
end

I’ve been trying to come up with a good strategy for testing this,  
since the test depends on time of execution. If I were using a  
conventional method, say:

def self.current  
find :all, :conditions =\> [‘do\_not\_show\_before \< ?’, Time.now]  
end

I would simply rewrite it like this:

def self.current(time = Time.now)  
find :all, :conditions =\> [‘do\_not\_show\_before \< ?’, time]  
end

and then only pass in a time parameter during testing. But I don’t  
know how to do with with named scopes because I cannot have optional  
arguments to a block.

For right now I’ve compromised by making a required time parameter as  
follows:

class Post \< ActiveRecord::Base  
named\_scope :current, lambda { |time|  
{ :conditions =\> [‘do\_not\_show\_before \< ?’, time] }  
}  
end

This means that every time I use the named\_scope I have to call it  
like this:

Post.current(Time.now).

I really don’t like this, but it does facilitate testing, which I  
accomplish (using shoulda and factory\_girl) thus:

context ‘An embargoed post’ do  
setup do  
@now = Time.now  
@post = Factory(:post, :no\_not\_show\_before =\> @now)  
end

```
should 'be in the named_scope "current" after the

```

do\_not\_show\_before datetime’ do  
assert\_contains Post.current(@now + 1.second), @post  
end

```
should 'not be in the named_scope "current" before the

```

embargoed\_until datetime’ do  
assert\_does\_not\_contain Post.current(@now - 1.second), @post  
end  
end

Is there a better way to accomplish this using named\_scopes?

-Sven

---

<div class="post-metadata">

**Author:** ![sven](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e47c2d/32.png) [@sven](https://www.ruby-forum.com/u/sven)\
**Post date:** [October 22, 2008, 6:00pm UTC](https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544/2 "2008-10-22T18:00:06Z")

</div>

On Wed, Oct 22, 2008 at 11:51 AM, Sven [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> …
> 
> Is there a better way to accomplish this using named\_scopes?

My first thought is to define the named\_scope as you have and also  
define a  
wrapper method. In the wrapper method, you can make the time parameter  
optional with a default of Time.now. Then you’d just use the wrapper  
method  
instead of the named\_scope directly. I don’t know how well that would  
play  
with chaining of named\_scopes.

Regards,  
Craig

---

<div class="post-metadata">

**Author:** ![sven](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e47c2d/32.png) [@sven](https://www.ruby-forum.com/u/sven)\
**Post date:** [October 22, 2008, 6:06pm UTC](https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544/3 "2008-10-22T18:06:01Z")

</div>

So something like this, perhaps:

class Post \< ActiveRecord::Base  
named\_scope :current\_as\_of, lambda { |time|  
{ :conditions =\> [‘do\_not\_show\_before \< ?’, time] }  
}

```
def self.current(time = Time.now)
  self.current_as_of(time)
end

```

end

I’m also concerned about chaining, and in particular about the  
behavior of things like will\_paginate. Hmmm.

Thanks,

Sven

---

<div class="post-metadata">

**Author:** ![sven](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e47c2d/32.png) [@sven](https://www.ruby-forum.com/u/sven)\
**Post date:** [October 22, 2008, 6:21pm UTC](https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544/4 "2008-10-22T18:21:52Z")

</div>

On Wed, Oct 22, 2008 at 12:05 PM, Sven [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end  
> end
> 
> I’m also concerned about chaining, and in particular about the  
> behavior of things like will\_paginate. Hmmm.

Yeah, that’s what I was thinking. Let us know how it works or if you do  
something else.

Regards,  
Craig

---

<div class="post-metadata">

**Author:** ![sven](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e47c2d/32.png) [@sven](https://www.ruby-forum.com/u/sven)\
**Post date:** [October 22, 2008, 6:58pm UTC](https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544/5 "2008-10-22T18:58:17Z")

</div>

Yes he did. I hadn’t seen that one and didn’t think of checking it.  
Ryan suggests exactly what you’ve proposed; I’ve tried it and it  
works. Thank you! This is much cleaner, and I get to keep using the  
named\_scope instead of a method.

Now if I can just find a way around my other method-to-named\_scope  
workaround problem ([http://groups.google.com/group/rubyonrails-talk/](http://groups.google.com/group/rubyonrails-talk/)  
browse\_thread/thread/a12f471c54a26b20) my code will be consistent once  
again 🙂

-Sven

---

<div class="post-metadata">

**Author:** ![sven](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e47c2d/32.png) [@sven](https://www.ruby-forum.com/u/sven)\
**Post date:** [October 22, 2008, 6:26pm UTC](https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544/6 "2008-10-22T18:26:01Z")

</div>

Actually, you could do something like this:

named\_scope :current, lambda { |\*args| { :conditions =\>  
[‘do\_not\_show\_before \< ?’, (args.first || Time.now)] } }

I knew Ryan B.’ screencast on named\_scope covered defaults. See:  
[http://railscasts.com/episodes/108](http://railscasts.com/episodes/108) .

Regards,  
Craig

---

<div class="post-metadata">

**Author:** ![sven](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e47c2d/32.png) [@sven](https://www.ruby-forum.com/u/sven)\
**Post date:** [October 22, 2008, 7:03pm UTC](https://www.ruby-forum.com/t/testing-time-dependent-named-scopes/151544/7 "2008-10-22T19:03:34Z")

</div>

On Wed, Oct 22, 2008 at 12:57 PM, Sven [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Yes he did. I hadn’t seen that one and didn’t think of checking it.  
> Ryan suggests exactly what you’ve proposed; I’ve tried it and it  
> works. Thank you! This is much cleaner, and I get to keep using the  
> named\_scope instead of a method.

Just to be sure Ryan gets the credit, I checked his site and then  
modified  
your code according to his example. 🙂

Craig
