[rspec-users] Controller spec: testing that scope is set

Michael Schuerig michael at schuerig.de
Sun Apr 19 18:41:58 EDT 2009

On Sunday 19 April 2009, Zach Dennis wrote:
> On Sun, Apr 19, 2009 at 2:09 PM, Michael Schuerig 
<michael at schuerig.de> wrote:
> > On Sunday 19 April 2009, Zach Dennis wrote:
> >> On Sun, Apr 19, 2009 at 12:27 PM, Michael Schuerig
> >
> > <michael at schuerig.de> wrote:
> >> > In a Rails controller I set the scope on a model class in an
> >> > around filter. I have defined expectations on the model classes,
> >> > and ideally, I would add a further expectation for the scope. Is
> >> > this already possible in some way? How would I go about adding
> >> > support a scope expectation?
> >>
> >> How are you setting the said scope?
> >
> > In an around filter. However, I don't want to test the around
> > filter mechanism, it might as well be rack middleware instead.
> Sorry, I don't know what scope means to you in your app. Can you
> share your around_filter?

Oops, sorry, I assumed the concept from ActiveRecord would be familiar. 
If you know ActiveRecord::Base#with_scope that's really all there is. A 
scope, within a block or through a proxy, defines options that are 
merged with the arguments to #find et al. This merging happens behind 
the scenes, therefore the scoped options are effective, but don't show 
up as arguments anywhere.

I'm using this in conjunction with a generic query representation 
(inspired by JSON Query) that is map through a combination of Rack 
middleware and generated around_filters, see below for a glimpse.


class PeopleController < ApplicationController
  include QueryScope

  query_scope :only => :index do
    # Only allow to filter and order by the
    # virtual name attribute.
    # This attribute is mapped onto the real
    # firstname and lastname attributes.
    allow     :name
    condition :name =>
      "LOWER(firstname || ' ' || lastname) :op LOWER(?)"
    order     :name => "lastname :dir, firstname :dir"

Somewhere in QueryScope

def query_scope(options = {}, &config_block)
  model_class = extract_resource!(options)
  builder = QueryScopeBuilder.new(config_block)
  around_filter(options) do |controller, action|
    req = builder.build_request_conditioner(controller.request)
    controller.instance_variable_set(:@offset_limit, req.offset_limit)
    model_class.send(:with_scope, :find => req.find_options, &action)

Michael Schuerig
mailto:michael at schuerig.de

More information about the rspec-users mailing list