On Sun, Apr 19, 2009 at 7:19 PM, Michael Schuerig <[email protected]> wrote: > On Monday 20 April 2009, David Chelimsky wrote: >> On Sun, Apr 19, 2009 at 5:41 PM, Michael Schuerig > <[email protected]> wrote: >> > On Sunday 19 April 2009, Zach Dennis wrote: >> >> On Sun, Apr 19, 2009 at 2:09 PM, Michael Schuerig >> > >> > <[email protected]> wrote: >> >> > On Sunday 19 April 2009, Zach Dennis wrote: >> >> >> On Sun, Apr 19, 2009 at 12:27 PM, Michael Schuerig >> >> > >> >> > <[email protected]> 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. >> >> It *is* familiar, but setting a model scope from the controller >> violates the widely-accepted guideline of skinny controllers and fat >> models. I'm guessing that's why Zach wasn't sure what you were >> talking about. > > My controllers are anorexic. The functionality I'm trying to spec is > completely generic, I just mix it into the controller. > > [snip] >> > 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) end >> > end >> >> Unless I'm mistaken, it is code like this outside models that was the >> underlying motivation for adding named scopes to active record. The >> reason it is problematic is that it tends to result in a lot of >> duplication outside the models, and makes the controllers really hard >> to understand. > > You are mistaken as there is no duplication at all. Among other things, > I have Rack middleware that maps request like (appropriately escaped) > > /resource/?[?name='Dav*'][/name] > > to a params hash like > > { :query => [{:attribute => 'name', :op => '=', :target => 'Dav*'}], > :order => [{:attribute => 'name'}] } > > This, in turn, is interpreted by a RequestConditioner (bad name) which > in this case would, with the help of some mappings passed to it, return > > rc.conditions == ["(firstname || ' ' || lastname) LIKE ?", 'Dav%'] > rc.order == 'lastname, firstname' > > As the last step, these pieces are used to define a scope around certain > controller actions. I could pass them explicitly to, say, #find, but > then I'd have to manually merge them with other conditions. > > As to whether this functionality belongs in the model -- I am against > it. What I've described is an adapter layer that translates from one > representation of a query to another. It is not at all related to the > core logic enclosed in the models. > > >> Consider this alternative: >> >> describe PeopleController do >> describe "GET index" do >> it "assigns a list of all people filtered by virtual name >> attributes" do people = [mock_model(Person)] >> Person.stub!(:all).and_return(people) >> people.should_receive(:with_virtual_names).and_return(people) >> get :index >> end >> end >> end >> >> class PeopleController >> def index >> @people = PeopleController.all.with_virtual_names >> end >> end > > That code is sclerotic. I'm building a RIA-client that only requests > JSON-formatted data from the server. Say, I add a date of birth column > to the people grid. Then the most I want to (and have to) do is ensure > that the requisite attribute is whitelisted for querying and contained > in the response data. (Yes, I have JSON "views" with accompanying > specs.) > > Taking your non-generic approach, I'd have to repeatedly write and > explicitly test, very similar code. Consider adding date of birth for > sorting and filtering to your example. Then consider writing another > controller that does roughly the same for movies with titles and release > dates. You'll end up with repetitive code. Of course, you're going to > factor out the repetition -- and that's where I already am. > > So, long story short, I still think I could make good use of a way to > define an expectation for a specific scope in effect during a #find. > Apart from my current case, this would make it possible to check on > dynamic scopes introduced in Rails 2.3.
So what does the controller's index method actually look like? > > Michael > > -- > Michael Schuerig > mailto:[email protected] > http://www.schuerig.de/michael/ > > _______________________________________________ > rspec-users mailing list > [email protected] > http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ rspec-users mailing list [email protected] http://rubyforge.org/mailman/listinfo/rspec-users
