Filters for finders

Is there a way to filter all finders for a model?
In my example, I have a TINYINT column called ‘active’. I wan’t to
somehow filter it so that all finders by default can’t see the records
where active=0.
I know that this could be done with SQL views, but there are complicated
reasons why I can’t do this.

Many thanks in advance.

Cheers,
Jon

Jon B. wrote:

Is there a way to filter all finders for a model?

It’s not automatic (i.e., you have to explicitly apply the filter), but
with_scope might help you out:

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

Aaron,

Thanks for your detailed reply.
My only problem with the with_scope method is that it doesn’t appear to
intercept dynamic finders (e.g. find_by_SKU( )).
Any ideas on how accomplish this with with_scope?

Thanks,
Jon

Aaron wrote:

On Dec 18, 9:25 pm, Adam B. [email protected]
wrote:

Jon B. wrote:

Is there a way to filter all finders for a model?It’s not automatic (i.e., you have to explicitly apply the filter), but
with_scope might help you out:

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

You can wrap a models find method inside a with_scope call. That way
all calls to find will be scoped. Here is an example:

class SomeClass < ActiveRecord::Base
class << self
def find(*args)
self.with_scope(:find => {:conditions => “active>0”}) do
super
end
end
end

end

All calls to find will automatically have the “active>0” condition
added.

If you access this class through an association from another class you
could add a :conditions argument to the association. Here is an
example:

class Menu < ActiveRecord::Base
has_many :items, :conditions => ‘active>0’
end

class Item < ActiveRecord::Base
belongs_to :menu
end

@menu.items returns a list of active items. Now maybe you don’t want
to always block access to inactive items. You can create multiple
named associations to the same class:

class Menu < ActiveRecord::Base
has_many :items,
has_many :active_items, :class_name => “Item”, :conditions =>
‘active>0’
end

Admin users could use the items association while everyone else goes
through active_items.

Aaron

On Dec 18, 9:25 pm, Adam B. [email protected]
wrote:

Jon B. wrote:

Is there a way to filter all finders for a model?It’s not automatic (i.e., you have to explicitly apply the filter), but
with_scope might help you out:

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

You can wrap a models find method inside a with_scope call. That way
all calls to find will be scoped. Here is an example:

class SomeClass < ActiveRecord::Base
class << self
def find(*args)
self.with_scope(:find => {:conditions => “active>0”}) do
super
end
end
end

end

All calls to find will automatically have the “active>0” condition
added.

If you access this class through an association from another class you
could add a :conditions argument to the association. Here is an
example:

class Menu < ActiveRecord::Base
has_many :items, :conditions => ‘active>0’
end

class Item < ActiveRecord::Base
belongs_to :menu
end

@menu.items returns a list of active items. Now maybe you don’t want
to always block access to inactive items. You can create multiple
named associations to the same class:

class Menu < ActiveRecord::Base
has_many :items,
has_many :active_items, :class_name => “Item”, :conditions =>
‘active>0’
end

Admin users could use the items association while everyone else goes
through active_items.

Aaron

On Dec 19, 2:26 pm, Jon B. [email protected] wrote:

My only problem with the with_scope method is that it doesn’t appear to
intercept dynamic finders (e.g. find_by_SKU( )).
Any ideas on how accomplish this with with_scope?

Jon,

Unfortunately, I don’t know how to make the dynamic finders respect the
with_scope. You can avoid using dynamic finders, but that’s prone to
error. If you come up with something please let me know.

Aaron

Hey,
to intercept dynamic finders, you just have to scope method_missing

class Klass
class << self

    alias :find_unrestricted :find
    def find(*options)
        self.with_scope( :find => { :conditions => 

restriction_condition } ) do
super(*options)
end
end

    alias :count_unrestricted :count
    def count(*options)
        self.with_scope( :find => { :conditions => 

restriction_condition } ) do
super(*options)
end
end

    def method_missing(method_id, *arguments)
        self.with_scope( :find => { :conditions => 

restriction_condition } ) do
super(method_id, *arguments)
end
end

    protected

    def restriction_condition
        ["#{self.table_name}.active = ?", true]
    end
end

end
Lori O. wrote:

On 12/21/06, Aaron [email protected] wrote:

Unfortunately, I don’t know how to make the dynamic finders respect the
with_scope. You can avoid using dynamic finders, but that’s prone to
error. If you come up with something please let me know.

Aaron

Has anyone got any ideas on this one? I have a database table that is
never
accessed on it’s own, always by it’s relationships to other tables. So
I
need a series of models, all pointing at the same table, but that
operate as
if they are within a “with_scope”.

Just to give a fer-instance…

Table People. Table Homes with foreign key owner, pointing to People.
I am
not interested in People. I am only interested in HomeOwners.

I need something like

class Person < ActiveRecord::Bass
end

class HomeOwner < Person
def self.find(*args)
with_scope( :find =>{ :conditions => “id in (select distinct(owner)
from
homes)” } ) do
super(*args)
end
end
end

Only I need it to be scoped for all the dynamic finders, and count, etc.

Regards, Lori

On 12/21/06, Aaron [email protected] wrote:

Unfortunately, I don’t know how to make the dynamic finders respect the
with_scope. You can avoid using dynamic finders, but that’s prone to
error. If you come up with something please let me know.

Aaron

Has anyone got any ideas on this one? I have a database table that is
never
accessed on it’s own, always by it’s relationships to other tables. So
I
need a series of models, all pointing at the same table, but that
operate as
if they are within a “with_scope”.

Just to give a fer-instance…

Table People. Table Homes with foreign key owner, pointing to People.
I am
not interested in People. I am only interested in HomeOwners.

I need something like

class Person < ActiveRecord::Bass
end

class HomeOwner < Person
def self.find(*args)
with_scope( :find =>{ :conditions => “id in (select distinct(owner)
from
homes)” } ) do
super(*args)
end
end
end

Only I need it to be scoped for all the dynamic finders, and count, etc.

Regards, Lori