harking-acts_as_graph 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (7) hide show
  1. data/CHANGELOG +10 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +3 -0
  4. data/Rakefile +0 -0
  5. data/init.rb +1 -0
  6. data/lib/acts_as_graph.rb +145 -0
  7. metadata +69 -0
data/CHANGELOG ADDED
@@ -0,0 +1,10 @@
1
+ = CHANGELOG
2
+
3
+ == Subversion
4
+
5
+ * Imported initial sources
6
+ * Added basic methods: incoming_edges, incoming_nodes, outgoing_edges and outgoing_nodes
7
+ * Dynamically define the edge class
8
+ * Create RGL graphs
9
+ * Refoactored from habtm to has_many :through
10
+ * Added patch for has_many :through from Marshall Roch
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 Aslak Hellesoy and Fiaz Sami
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,3 @@
1
+ = acts_as_graph
2
+
3
+ See the documentation in lib/acts_as_graph.rb
data/Rakefile ADDED
File without changes
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'acts_as_graph'
@@ -0,0 +1,145 @@
1
+ module ActiveRecord # :nodoc:
2
+ module Acts #:nodoc:
3
+ module Graph # :nodoc:
4
+ def self.included(base) # :nodoc:
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ # Author: Originally by Tammer Saleh (tammersaleh.com)
9
+ # Updated to rails 2.3.2 by Shayne Huddleston and maintained by George Harkin <montana.harkin@gmail.com>
10
+
11
+ # Specify this act if you want the model to represent nodes in a directed graph structure.
12
+ # This act optionally allows you to perform various graph algorithms on your graphs using
13
+ # RGL (http://rgl.rubyforge.org/rgl/index.html) if you have it installed.
14
+ #
15
+ # This act requires that you have a join table for the edges. Unless you specify otherwise,
16
+ # the name of the join table is expected to be the singular name of the nodes table - suffixed
17
+ # by <tt>_edges</tt>. The join table should have at least three columns - <tt>id</tt>,
18
+ # <tt>from_id</tt> and <tt>to_id</tt>.
19
+ #
20
+ # class Employee < ActiveRecord::Base
21
+ # acts_as_graph
22
+ # end
23
+ #
24
+ # Example :
25
+ #
26
+ # fred ---------> wilma
27
+ # | |
28
+ # +--> barney <---+
29
+ #
30
+ # # Define the nodes
31
+ # fred = Employee.create(:name => "fred")
32
+ # wilma = Employee.create(:name => "wilma")
33
+ # barney = Employee.create(:name => "barney")
34
+ #
35
+ # # Define the edges
36
+ # EmployeeEdge.create(:from => fred, :to => wilma)
37
+ # EmployeeEdge.create(:from => fred, :to => barney)
38
+ # EmployeeEdge.create(:from => wilma, :to => barney)
39
+ #
40
+ # # Query the nodes
41
+ # barney.incoming_nodes # => [fred, wilma]
42
+ # wilma.outgoing_edges # => [wilma_barney]
43
+ #
44
+ # # Get all of the edges
45
+ # Employee.edges # => Array of EmployeeEdge
46
+ #
47
+ # # Get an RGL graph representing all of the edges
48
+ # # (Requires RGL: http://rgl.rubyforge.org/rgl/index.html)
49
+ # Employee.graph # => RGL::DirectedAdjacencyGraph
50
+ #
51
+ # # Create an image file (Requires RGL and Graphviz: http://www.graphviz.org/)
52
+ # require 'rgl/dot'
53
+ # Employee.graph.write_to_graphic_file('png')
54
+ #
55
+ # You don't have to specify a class for the edges.
56
+ # After specifying the act, a class for the edges will be dynamically defined. Example:
57
+ #
58
+ # class EmployeeEdge
59
+ # def from; ...;end
60
+ # def to; ...;end
61
+ # end
62
+ #
63
+ # However, should you want to add more behaviour to the edge class, you're free to define it yourself,
64
+ # as well as add additional columns to the associated table.
65
+ #
66
+ # The following instance methods are added to the class after specifying the act:
67
+ # * outgoing_edges : Returns all edges pointing out from this node.
68
+ # * incoming_edges : Returns all edges pointing in to this node.
69
+ # * outgoing_nodes : Returns all nodes that the outgoing edges point to.
70
+ # * incoming_nodes : Returns all nodes that the incoming edges point from.
71
+ #
72
+ # The following class methods are added to the class after specifying the act:
73
+ # * edges : Returns all the edges in the database.
74
+ # * graph : Returns a RGL::DirectedAdjacencyGraph representing all the nodes and edges in the database.
75
+ #
76
+ module ClassMethods
77
+ def acts_as_graph(options = {})
78
+ # TODO: options for
79
+ # :include_from (ignored - always true if order is set)
80
+ # :include_to (ignored - always true if order is set)
81
+
82
+ class_name = options[:class_name] || "#{self.name}Edge"
83
+ join_table = options[:join_table] || class_name.pluralize.underscore
84
+ from_key = options[:from_key] || 'from_id'
85
+ to_key = options[:to_key] || 'to_id'
86
+ order = options[:order]
87
+
88
+ eval <<-EOF
89
+ class ::#{class_name} < ::ActiveRecord::Base
90
+ belongs_to :from, :class_name => '#{self.name}', :foreign_key => '#{from_key}'
91
+ belongs_to :to, :class_name => '#{self.name}', :foreign_key => '#{to_key}'
92
+ end
93
+ EOF
94
+
95
+ has_many :outgoing_edges, {
96
+ :class_name => class_name,
97
+ :foreign_key => from_key,
98
+ :include => :to,
99
+ :order => order,
100
+ :dependent => :destroy
101
+ }
102
+
103
+ has_many :incoming_edges, {
104
+ :class_name => class_name,
105
+ :foreign_key => to_key,
106
+ :include => :from,
107
+ :order => order,
108
+ :dependent => :destroy
109
+ }
110
+
111
+ has_many :outgoing_nodes, :through => :outgoing_edges, :source => :to, :order => order
112
+ has_many :incoming_nodes, :through => :incoming_edges, :source => :from, :order => order
113
+
114
+ class_eval <<-EOV
115
+ include ActiveRecord::Acts::Graph::InstanceMethods
116
+
117
+ def self.edges
118
+ # Ideally we should :include => [:from, :to] but the SQL fails...
119
+ #{class_name}.find :all
120
+ end
121
+
122
+ def self.graph
123
+ begin
124
+ require 'rgl/adjacency'
125
+ dg = RGL::DirectedAdjacencyGraph.new
126
+ edges.each{|edge| dg.add_edge(edge.from, edge.to)}
127
+ find(:all).each{|vertex| dg.add_vertex(vertex)}
128
+ dg
129
+ rescue MissingSourceFile
130
+ raise "RGL must be installed when using the graph method. See http://rgl.rubyforge.org/rgl/index.html"
131
+ end
132
+ end
133
+
134
+ EOV
135
+ end
136
+
137
+ end
138
+
139
+ module InstanceMethods #:nodoc:
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ ActiveRecord::Base.send :include, ActiveRecord::Acts::Graph
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: harking-acts_as_graph
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Tammer Saleh
8
+ - Shayne Huddleston
9
+ - George Harkin
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-07-20 00:00:00 -07:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: activerecord
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 2.3.2
26
+ version:
27
+ description: acts_as_graph is a Rails plugin that facilitates a Graph like interface to ActiveRecord.
28
+ email: montana.harkin@gmail.com
29
+ executables: []
30
+
31
+ extensions: []
32
+
33
+ extra_rdoc_files: []
34
+
35
+ files:
36
+ - CHANGELOG
37
+ - MIT-LICENSE
38
+ - README
39
+ - Rakefile
40
+ - init.rb
41
+ - lib/acts_as_graph.rb
42
+ has_rdoc: false
43
+ homepage: http://github.com/harking/acts_as_graph
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.2.0
65
+ signing_key:
66
+ specification_version: 2
67
+ summary: acts_as_graph is a Rails plugin that facilitates a Graph like interface to ActiveRecord.
68
+ test_files: []
69
+