iBrasten

My methods of calculating time are far superior to yours, in every way.

 

This is the blog of Brasten Sager, a freelance software developer, Mariners fan, guitarist, haphazard philosopher.

Edge report: with_scope protected

June 19, 2007 @ 12:59 PM

I knew all along that using with_scope outside my models was a bad idea, but I did it anyway. So once this little change came through, I had to rethink some of my code…

Just to throw this out there – let’s call it peer-review – my new method of encapsulating with_scope usages sort of piggy-backs on finder encapsulation.

Take, for example, the following code:

1
2
3
4
5
6
7
8
9
10
11
12

class Post < ActiveRecord::Base
  def self.find_active
    # ... some finder code to return all active posts
  end
end

class PostsController < ApplicationController
  def index
    @posts = Post::find_active
  end
end

… despite my habit of encapsulating finders, I still found myself doing this:

1
2
3
4
5
  
# In around-filter or action
Post::with_scope( ... conditions ... ) do
  # ... yield or something
end

– Obviously, BAD. So the alternative is to do something like Post::scope_by_active or something. What about adding a fairly simple block_given? condition to the existing find_active method? Use your imagination on the implementation of that, but the usage would now look something like this:

1
2
3
4
5
6
7
8
  
# No block, returns all active
@posts = Post::find_active

# block, scopes to active, returns result of block.
@my_posts = Post::find_active do
              Post::find_by_user( user )
            end

Soooo… peer-review away!

2 Responses to “Edge report: with_scope protected”

  1. I’m code to same construct

    def self.find_something(*opts) # :block - optional with_scope(…) do block_given? ? yield : find(:all, *opts) end end

    Sergey

  2. Nice! That’s identical to my code. The initial temptation was to use an IF statement, but the yield or find(:all) is much cleaner I think.

    Plus, I like seeing it as an implicit find(:all) if no block is specified, rather than a “IF you pass a block, it’ll do this, OTHERWISE, it’ll do that.”

    Thanks for the comment!

    brasten