Acts As Filterable
- Filed under Security & Protection and ActiveRecord
- Developed by Mark Chadwick (markchadwick)
== 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


