Railsify!

Acts As Filterable

== Simple Filtering Example

This will implement the acts_as_filterable mixin for an ActiveRecord
class.  It'll...uhh...you know.  Filter stuff.  Let's see an example:

 class Badger < ActiveRecord::Base
   has_many :beers
 end
  
 frank = Badger.create(:name => 'Frank')
 james = Badger.create(:name => 'James')
 drinky = Badger.create(:name => 'Drinky')
  
This is great.  We have a couple badgers, everything is going pretty
smooth.  Frank, James, Drinky have fun adventures damn-near constantly.
Though, as we could have guessed, Drinky has a <i>bit</i> of a drinking
problem.  We'd really rather just not even know he exists if he's had
too much.  Really, we'd rather not know about <i>any</i> badgers who
have been drinking.
 
 class Badger < ActiveRecord::Base
   has_many   :beers
   acts_as_filterable
   
   def too_much_to_drink?
     beers.size > 3
   end
   
   invisible_if :too_much_to_drink?
 end
 
Cool.  So, at the moment, we're kicking:
 
 Badger.find(:all).each do |badger|
   puts "#{badger.name} drank #{badger.beers.size} Beers!"
 end
 > Frank drank 0 Beers!
 > James drank 0 Beers!
 > Drinky drank 0 Beers!
 
Now!  On to the drinking!
 
 frank.beers << [Beer.create, Beer.create, Beer.create]
 james.beers << [Beer.create, Beer.create]
 drinky.beers << [Beer.create, Beer.create, Beer.create, Beer.create]
 
Christallmighty.  Looks like Drinky's had too much to drink again.  Let's
run the roll call, to see if anyone's going to tell us semi-truthful stories
with copious volume and slurring.

 Badger.find(:all).each do |badger|
   puts "#{badger.name} drank #{badger.beers.size} Beers!"
 end
 > Frank drank 3 Beers!
 > James drank 2 Beers!

== Instantiating Invisible Items

Effing sweet.  Drinky's just gone.  His antics got a little old.  But
let's say Frank wants to go find Drinky...he has a awesome story to
tell him.

 Badger.find_by_name('Drinky')
 > nil
 Badger.find(3) # Drinky's id
 > ActiveRecord::RecordNotFound exception and so-forth!
  
No.  Drinky's gone until he sobers up.  End of story.

== Making Exceptions

Well, let's say that Frank can handle his own a bit better than Drinky
can.  He just gets friendly, and tells good stories.  Nothing ends up
broken, and he leaves no stains on anyone's carpets.  We'll let Frank
drink as much as he wants.

 class Badger < ActiveRecord::Base
   has_many   :beers
   acts_as_filterable
   
   def too_much_to_drink?
     beers.size > 3
   end
   
   def is_frank?
   	name == "Frank"
   end
   
   invisible_if :too_much_to_drink?
   visible_if   :is_frank?
 end
 
The results are as expected.  The rules are executed in sequential order.
If we had a deleted flag or something -- and we didn't want to waste our
time screwing around with access rules if it evaluated, we could just pass
a flag as follows:
 invisible_if :deleted?, :always => true
and execution of the rules would halt if that rule was evaluated to true.
== The Big Exception

Let's say Animal Control rolls into town, and they want a head count on
badgers -- drunk or not.  We need to make some kinda back-door to get
accurate info on all our model objects.  Check it out:

 ActiveRecord::Base.security_ignore do
   Badger.find(:all).each do |badger|
     puts badger.name
   end
 end
 > Frank
 > James
 > Drinky

Ah, the good times.
   

Last updated: September 10, 2007 14:50