dm_is_a_tree 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/LICENSE +20 -0
  2. data/README +4 -0
  3. data/Rakefile +58 -0
  4. data/TODO +4 -0
  5. data/lib/dm_is_a_tree.rb +123 -0
  6. metadata +60 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Timothy Bennett
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,4 @@
1
+ templates
2
+ =================
3
+
4
+ A plugin for DataMapper that provides acts_as_tree functionality similar to that in AR.
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'spec/rake/spectask'
4
+
5
+ GEM = "dm_is_a_tree"
6
+ VERSION = "0.2.0"
7
+ AUTHOR = "Timothy Bennett"
8
+ EMAIL = "lanaer@lanaer.com"
9
+ HOMEPAGE = "http://lanaer.com/"
10
+ SUMMARY = "A plugin for DataMapper that allows model objects to be a part of a heirarchal tree structure. Based on the acts_as_tree plugin for ActiveRecord."
11
+
12
+ spec = Gem::Specification.new do |s|
13
+ s.name = GEM
14
+ s.version = VERSION
15
+ s.platform = Gem::Platform::RUBY
16
+ s.has_rdoc = true
17
+ s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
18
+ s.summary = SUMMARY
19
+ s.description = s.summary
20
+ s.author = AUTHOR
21
+ s.email = EMAIL
22
+ s.homepage = HOMEPAGE
23
+
24
+ s.add_dependency "datamapper", ">=0.2.3"
25
+
26
+ s.require_path = 'lib'
27
+ s.autorequire = GEM
28
+ s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,specs}/**/*")
29
+ end
30
+
31
+ Rake::GemPackageTask.new(spec) do |pkg|
32
+ pkg.gem_spec = spec
33
+ end
34
+
35
+ task :install => [:package] do
36
+ sh %{sudo gem install pkg/#{GEM}-#{VERSION}}
37
+ end
38
+
39
+ desc "Run all specs"
40
+ Spec::Rake::SpecTask.new('specs') do |t|
41
+ t.spec_opts = ["--format", "specdoc", "--colour"]
42
+ t.spec_files = Dir['spec/**/*_spec.rb'].sort
43
+ end
44
+
45
+ desc "Run all specs output html"
46
+ Spec::Rake::SpecTask.new('specs_html') do |t|
47
+ t.spec_opts = ["--format", "html"]
48
+ t.libs = ['lib', 'server/lib' ]
49
+ t.spec_files = Dir['spec/**/*_spec.rb'].sort
50
+ end
51
+
52
+ desc "RCov"
53
+ Spec::Rake::SpecTask.new('rcov') do |t|
54
+ t.spec_opts = ["--format", "specdoc", "--colour"]
55
+ t.spec_files = Dir['spec/**/*_spec.rb'].sort
56
+ t.libs = ['lib', 'server/lib' ]
57
+ t.rcov = true
58
+ end
data/TODO ADDED
@@ -0,0 +1,4 @@
1
+ TODO:
2
+ Fix LICENSE with your name
3
+ Fix Rakefile with your name and contact info
4
+ Add your code to lib/<%= name %>.rb
@@ -0,0 +1,123 @@
1
+ require 'data_mapper'
2
+
3
+ module DataMapper
4
+ module Is
5
+ module Tree
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ # An extension to DataMapper to easily allow the creation of tree structures from your DataMapper Models.
11
+ # This requires a foreign key property for your model, which by default would be called :parent_id.
12
+ #
13
+ # Example:
14
+ #
15
+ # class Category < DataMapper::Base
16
+ # property :parent_id, :integer
17
+ # property :name, :string
18
+ #
19
+ # is_a_tree :order => "name"
20
+ # end
21
+ #
22
+ # root
23
+ # +- child
24
+ # +- grandchild1
25
+ # +- grandchild2
26
+ #
27
+ # root = Category.create("name" => "root")
28
+ # child = root.children.create("name" => "child")
29
+ # grandchild1 = child1.children.create("name" => "grandchild1")
30
+ # grandchild2 = child2.children.create("name" => "grandchild2")
31
+ #
32
+ # root.parent # => nil
33
+ # child.parent # => root
34
+ # root.children # => [child]
35
+ # root.children.first.children.first # => grandchild1
36
+ # Category.first_root # => root
37
+ # Category.roots # => [root]
38
+ #
39
+ # The following instance methods are added:
40
+ # * <tt>children</tt> - Returns all nodes with the current node as their parent, in the order specified by
41
+ # <tt>:order</tt> (<tt>[grandchild1, grandchild2]</tt> when called on <tt>child</tt>)
42
+ # * <tt>parent</tt> - Returns the node referenced by the foreign key (<tt>:parent_id</tt> by
43
+ # default) (<tt>root</tt> when called on <tt>child</tt>)
44
+ # * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node
45
+ # (<tt>[grandchild2]</tt> when called on <tt>grandchild1</tt>)
46
+ # * <tt>generation</tt> - Returns all the children of the parent, including the current node (<tt>
47
+ # [grandchild1, grandchild2]</tt> when called on <tt>grandchild1</tt>)
48
+ # * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[root, child1]</tt>
49
+ # when called on <tt>grandchild2</tt>)
50
+ # * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>grandchild2</tt>)
51
+ module ClassMethods
52
+ # Configuration options are:
53
+ #
54
+ # * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
55
+ # * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
56
+ # * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
57
+ def is_a_tree(options = {})
58
+ configuration = { :foreign_key => "parent_id" }
59
+ configuration.update(options) if options.is_a?(Hash)
60
+
61
+ belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
62
+ has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order]
63
+
64
+ include DataMapper::Is::Tree::InstanceMethods
65
+
66
+ class_eval <<-CLASS
67
+ def self.roots
68
+ self.all :#{configuration[:foreign_key]} => nil, :order => #{configuration[:order].inspect}
69
+ end
70
+
71
+ def self.first_root
72
+ self.first :#{configuration[:foreign_key]} => nil, :order => #{configuration[:order].inspect}
73
+ end
74
+ CLASS
75
+
76
+ class << self
77
+ alias_method :root, :first_root # for people used to the ActiveRecord acts_as_tree
78
+ end
79
+ end
80
+
81
+ alias_method :can_has_tree, :is_a_tree # just for fun ;)
82
+ end
83
+
84
+ module InstanceMethods
85
+ # Returns list of ancestors, starting with the root.
86
+ #
87
+ # grandchild1.ancestors # => [root, child]
88
+ def ancestors
89
+ node, nodes = self, []
90
+ nodes << node = node.parent while node.parent
91
+ nodes.reverse
92
+ end
93
+
94
+ # Returns the root node of the current node’s tree.
95
+ #
96
+ # grandchild1.root # => root
97
+ def root
98
+ node = self
99
+ node = node.parent while node.parent
100
+ node
101
+ end
102
+
103
+ # Returns all siblings of the current node.
104
+ #
105
+ # grandchild1.siblings # => [grandchild2]
106
+ def siblings
107
+ generation - [self]
108
+ end
109
+
110
+ # Returns all children of the current node’s parent.
111
+ #
112
+ # grandchild1.generation # => [grandchild1, grandchild2]
113
+ def generation
114
+ parent ? parent.children : self.class.roots
115
+ end
116
+
117
+ alias_method :self_and_siblings, :generation # for those used to the ActiveRecord acts_as_tree
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ DataMapper::Base.send(:include, DataMapper::Is::Tree)
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: dm_is_a_tree
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.2.0
7
+ date: 2007-12-06 00:00:00 -08:00
8
+ summary: A plugin for DataMapper that allows model objects to be a part of a heirarchal tree structure. Based on the acts_as_tree plugin for ActiveRecord.
9
+ require_paths:
10
+ - lib
11
+ email: lanaer@lanaer.com
12
+ homepage: http://lanaer.com/
13
+ rubyforge_project:
14
+ description: A plugin for DataMapper that allows model objects to be a part of a heirarchal tree structure. Based on the acts_as_tree plugin for ActiveRecord.
15
+ autorequire: dm_is_a_tree
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Timothy Bennett
31
+ files:
32
+ - LICENSE
33
+ - README
34
+ - Rakefile
35
+ - TODO
36
+ - lib/dm_is_a_tree.rb
37
+ test_files: []
38
+
39
+ rdoc_options: []
40
+
41
+ extra_rdoc_files:
42
+ - README
43
+ - LICENSE
44
+ - TODO
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ requirements: []
50
+
51
+ dependencies:
52
+ - !ruby/object:Gem::Dependency
53
+ name: datamapper
54
+ version_requirement:
55
+ version_requirements: !ruby/object:Gem::Version::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 0.2.3
60
+ version: