forked from jeremyevans/sequel
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add subclasses plugin, for recording all of a models subclasses and d…
…escendent classes The Subclasses plugin keeps track of all subclasses of the current model class. Direct subclasses are available via the subclasses method, and all descendent classes are available via the descendents method. c = Class.new(Sequel::Model) c.plugin :subclasses sc1 = Class.new(c) sc2 = Class.new(c) ssc1 = Class.new(sc1) c.subclasses # [sc1, sc2] sc1.subclasses # [ssc1] sc2.subclasses # [] ssc1.subclasses # [] c.descendents # [sc1, ssc1, sc2]
- Loading branch information
1 parent
6d0611c
commit b75bf19
Showing
4 changed files
with
100 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
module Sequel | ||
module Plugins | ||
# The Subclasses plugin keeps track of all subclasses of the | ||
# current model class. Direct subclasses are available via the | ||
# subclasses method, and all descendent classes are available via the | ||
# descendents method. | ||
# | ||
# c = Class.new(Sequel::Model) | ||
# c.plugin :subclasses | ||
# sc1 = Class.new(c) | ||
# sc2 = Class.new(c) | ||
# ssc1 = Class.new(sc1) | ||
# c.subclasses # [sc1, sc2] | ||
# sc1.subclasses # [ssc1] | ||
# sc2.subclasses # [] | ||
# ssc1.subclasses # [] | ||
# c.descendents # [sc1, ssc1, sc2] | ||
module Subclasses | ||
# Initialize the subclasses instance variable for the model. | ||
def self.apply(model, &block) | ||
model.instance_variable_set(:@subclasses, []) | ||
end | ||
|
||
module ClassMethods | ||
# All subclasses for the current model. Does not | ||
# include the model itself. | ||
attr_reader :subclasses | ||
|
||
# All descendent classes of this model. | ||
def descendents | ||
subclasses.map{|x| [x] + x.descendents}.flatten | ||
end | ||
|
||
# Add the subclass to this model's current subclasses, | ||
# and initialize a new subclasses instance variable | ||
# in the subclass. | ||
def inherited(subclass) | ||
super | ||
subclasses << subclass | ||
subclass.instance_variable_set(:@subclasses, []) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
require File.join(File.dirname(__FILE__), "spec_helper") | ||
|
||
describe Sequel::Model, "Subclasses plugin" do | ||
before do | ||
@c = Class.new(Sequel::Model) | ||
@c.plugin :subclasses | ||
end | ||
|
||
specify "#subclasses should record direct subclasses of the given model" do | ||
@c.subclasses.should == [] | ||
|
||
sc1 = Class.new(@c) | ||
@c.subclasses.should == [sc1] | ||
sc1.subclasses.should == [] | ||
|
||
sc2 = Class.new(@c) | ||
@c.subclasses.should == [sc1, sc2] | ||
sc1.subclasses.should == [] | ||
sc2.subclasses.should == [] | ||
|
||
ssc1 = Class.new(sc1) | ||
@c.subclasses.should == [sc1, sc2] | ||
sc1.subclasses.should == [ssc1] | ||
sc2.subclasses.should == [] | ||
end | ||
|
||
specify "#descendents should record all descendent subclasses of the given model" do | ||
@c.descendents.should == [] | ||
|
||
sc1 = Class.new(@c) | ||
@c.descendents.should == [sc1] | ||
sc1.descendents.should == [] | ||
|
||
sc2 = Class.new(@c) | ||
@c.descendents.should == [sc1, sc2] | ||
sc1.descendents.should == [] | ||
sc2.descendents.should == [] | ||
|
||
ssc1 = Class.new(sc1) | ||
@c.descendents.should == [sc1, ssc1, sc2] | ||
sc1.descendents.should == [ssc1] | ||
sc2.descendents.should == [] | ||
ssc1.descendents.should == [] | ||
|
||
sssc1 = Class.new(ssc1) | ||
@c.descendents.should == [sc1, ssc1, sssc1, sc2] | ||
sc1.descendents.should == [ssc1, sssc1] | ||
sc2.descendents.should == [] | ||
ssc1.descendents.should == [sssc1] | ||
sssc1.descendents.should == [] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters