> > So my question is... were my assumptions wrong (ie. my reasonings for
> > implementing :include) and will :include just not be supported and
> > should I just use the :select, :join combonation from this point?
>
> I understand the mechanics of the patch, but not the benefit. What's
> the use case where you want to scope-in :includes?

Ok, this is basically where the need for this came from (a bit long,
but I hope it's the detail you're looking for :).

I implemented a scoping filter that is similar to the one found at
this page (see the sections closer to the bottom titled
"ScopedAccess::ClassScoping" and "More ideas to be implemented") ...

http://habtm.com/articles/2006/02/22/nested-with_scope

My web app supports many seperate "websites" (sub-sites) and each site
should not be able to view data from others, only their own.  So my
initial option is to add a condition to all model find (Model.find)
calls specifying the current site that's being viewed (based on
domain) to make sure that a user from site X can't view data from site
Y from a given domain.

This can get messy and error prone due to adding the same condition
line after line and the developer may forget to add the condition to
new code.

So I decided to implement a scoping filter (again, similar to the
above implementation) which would automatically add the given
condition to the models that required them.

My models look similar to this...

- SiteRoot: contains data (id, domain) about each sub-site of the app
- SiteInfo: contains data that can change on a more frequent basis and
has a foreign key to SiteRoot
- And then SiteSpecificModels which contain a foreign key to SiteInfo,
NOT SiteRoot.

So based on this layout, my scope filter would contain something like this...
:find => {:include => [:site_root], :conditions => 'site_root.site_id = X'}

The :include is used to connect my site specific models to the root
information and this would be used to automatically filter my models
to the given sub-site.

So now I have at least one :include in use now (from the scope filter)
in the context of a controllers method.  Now within the controller
method I may include and additional find on the model which may add
another :include option to it's query.  With this scenario, the
include's now have to be merged because of the outer scoping.

ex.
class WidgetController < ApplicationController
  around_filter ScopedFilter.new(SiteWidget, {:find => {:include =>
[:site_root], :condtions => 'site_root.site_id = X'}})

  def show_widgets
    @widgets = Widget.find :all, :include => [:some_other_relation]
  end
end

In this scenario the Widget.find will have to merge its :include with
the :include in the scoped filter to get the desired results.

Now back to the :select, :joins combo point I brought up in my eariler
message.  I could have used :joins in the scope filter instead of
:include, but when I did that, inner finds (a find done in a
controllers method) would be using a "select *" by default and this
would screw up the id fields (only one field of the same name is
returned) from multiple tables therefore returning incorrect results. 
A custom :select could be added to the inner find, but this would just
add the same kind repetition as adding conditions to all the model
finds, which the scope filter is trying to remove.

So in ending, I added support for :include to get the results I needed
in the cleanest way I could come up with. :)  Does this clear things
up?  Again, I could be thinking about this the wrong way, so please
tell me if this is the case.

Thanks again,
Andrew
_______________________________________________
Rails-core mailing list
Rails-core@lists.rubyonrails.org
http://lists.rubyonrails.org/mailman/listinfo/rails-core

Reply via email to