ancestry 2.1.0 → 2.2.0

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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NzllMWZkZTQwYWVlNTVlZTdiYzJiMWMxZGZhYTY1YjlkYzNiMzM4Yw==
5
- data.tar.gz: !binary |-
6
- ZWRkMWYxOWZhOTJiNjU2MTE2ZTcyYWIwM2FlNmVmNjk0NjBkZGE2ZQ==
2
+ SHA1:
3
+ metadata.gz: 1b34c7c664ec5c1a9ac92379c65d9ea196658a3e
4
+ data.tar.gz: 2d9ff6493829ef26b6b8f3591404f7567139c717
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZDg4NTk4ODJiZmQ5NjAxMThkMDNhNjg5NTk3ZTJkN2IzN2QxMTY5OWIwNTgz
10
- OTg2MzVjY2Q3MWEyNTEzZDUzNjc4OTA5NWVhNTFiNWJjYjFiMTQxNjhkYzM5
11
- ODNlY2Y0MmIwZDc2ODQ4YTRiNmYxMWMwOTJiNzE0NDZmMDlhZGQ=
12
- data.tar.gz: !binary |-
13
- N2E1ZjAwY2M1YjkzZTBlNWRkNDQ0ZTVlMDM3OTg3YmE0ZDgwMzNlNTdjOTFh
14
- Y2NkYWY0NGUwNDFjZWI3OTZkMTAwMTBmNDI4OWZlOGQyMDRiZmQxOTgyOWFi
15
- ZGFmYzk1YTExNjFhYTczNzIxMGE2NGVlZTA4ZGMwYWViMjU3NGE=
6
+ metadata.gz: d4b6408a4e4582b8cb654e4d38560f1f7b0b743b55023ff6668449a75847874036975faf53c74c18e75fbc59c6eb6d8d1c3bd7d22b28ce97595bcd5d56bd1f49
7
+ data.tar.gz: b06389bb0d03045bd0f9f82ab2dac3db63c8ca2996c87bcc4f46bb9b71d876090bc136b928cd5ac9d2c3c6b62ed48cd0ca2175e5c5e9a0f6c2e169a6ef24e005
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Stefan Kroes
1
+ Copyright (c) 2016 Stefan Kroes
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,5 +1,7 @@
1
- {<img src="https://travis-ci.org/stefankroes/ancestry.png?branch=master" alt="Build Status" />}[https://travis-ci.org/stefankroes/ancestry]
2
- {<img src="https://coveralls.io/repos/stefankroes/ancestry/badge.png" alt="Coverage Status" />}[https://coveralls.io/r/stefankroes/ancestry]
1
+ {<img src="https://travis-ci.org/stefankroes/ancestry.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/stefankroes/ancestry]
2
+ {<img src="https://coveralls.io/repos/stefankroes/ancestry/badge.svg" alt="Coverage Status" />}[https://coveralls.io/r/stefankroes/ancestry]
3
+ {<img src="https://badges.gitter.im/Join Chat.svg" alt="Gitter" />}[https://gitter.im/stefankroes/ancestry?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge]
4
+ {<img src="https://hakiri.io/github/stefankroes/ancestry/master.svg" alt="Security" />}[https://hakiri.io/github/stefankroes/ancestry/master]
3
5
 
4
6
  = Ancestry
5
7
 
@@ -9,20 +11,51 @@ Ancestry is a gem/plugin that allows the records of a Ruby on Rails ActiveRecord
9
11
 
10
12
  To apply Ancestry to any ActiveRecord model, follow these simple steps:
11
13
 
12
- 1. Install
13
- - <b>Rails 2</b>
14
- - See 1-3-stable branch
15
- - <b>Rails 3</b>
16
- - Add to Gemfile: <b>gem 'ancestry'</b>
17
- - Install required gems: <b>bundle install</b>
18
-
19
- 2. Add ancestry column to your table
20
- - Create migration: <b>rails g migration add_ancestry_to_[table] ancestry:string</b>
21
- - Add index to migration: <b>add_index [table], :ancestry</b> (UP) / <b>remove_index [table], :ancestry</b> (DOWN)
22
- - Migrate your database: <b>rake db:migrate</b>
23
-
24
- 3. Add ancestry to your model
25
- - Add to app/models/[model].rb: <b>has_ancestry</b>
14
+ == Install
15
+ === Rails 2
16
+ - See 1-3-stable branch
17
+ === Rails 3 and 4
18
+ - Add to Gemfile:
19
+ # Gemfile
20
+
21
+ gem 'ancestry'
22
+ - Install required gems:
23
+ $ bundle install
24
+
25
+ == Add ancestry column to your table
26
+ - Create migration:
27
+ $ rails g migration add_ancestry_to_[table] ancestry:string
28
+ - Add index to migration:
29
+ # db/migrate/[date]_add_ancestry_to_[table].rb
30
+
31
+ class AddAncestryTo[Table] < ActiveRecord::Migration
32
+ # Rails 4 Syntax
33
+ def change
34
+ add_column [table], :ancestry, :string
35
+ add_index [table], :ancestry
36
+ end
37
+
38
+ # Rails 3 Syntax
39
+ def up
40
+ add_column [table], :ancestry, :string
41
+ add_index [table], :ancestry
42
+ end
43
+
44
+ def down
45
+ remove_column [table], :ancestry
46
+ remove_index [table], :ancestry
47
+ end
48
+
49
+ - Migrate your database:
50
+ $ rake db:migrate
51
+
52
+ == Add ancestry to your model
53
+ - Add to app/models/[model].rb:
54
+ # app/models/[model.rb]
55
+
56
+ class [Model] < ActiveRecord::Base
57
+ has_ancestry
58
+ end
26
59
 
27
60
  Your model is now a tree!
28
61
 
@@ -57,7 +90,7 @@ To navigate an Ancestry model, use the following methods on any instance / recor
57
90
  child_ids Returns a list of child ids
58
91
  has_children? Returns true if the record has any children, false otherwise
59
92
  is_childless? Returns true is the record has no children, false otherwise
60
- siblings Scopes the model on siblings of the record, the record itself is included
93
+ siblings Scopes the model on siblings of the record, the record itself is included*
61
94
  sibling_ids Returns a list of sibling ids
62
95
  has_siblings? Returns true if the record's parent has more than one child
63
96
  is_only_child? Returns true if the record is the only child of its parent
@@ -67,6 +100,8 @@ To navigate an Ancestry model, use the following methods on any instance / recor
67
100
  subtree_ids Returns a list of all ids in the record's subtree
68
101
  depth Return the depth of the node, root nodes are at depth 0
69
102
 
103
+ * If the record is a root, other root records are considered siblings
104
+
70
105
  = Options for has_ancestry
71
106
 
72
107
  The has_ancestry methods supports the following options:
@@ -174,6 +209,23 @@ To get the arranged nodes as a nested array of hashes for serialization:
174
209
  }
175
210
  ]
176
211
 
212
+ You can also supply your own serialization logic using blocks:
213
+
214
+ For example, using Active Model Serializers:
215
+
216
+ TreeNode.arrange_serializable do |parent, children|
217
+ MySerializer.new(parent, children: children)
218
+ end
219
+
220
+ Or plain hashes:
221
+
222
+ TreeNode.arrange_serializable do |parent, children|
223
+ {
224
+ my_id: parent.id
225
+ my_children: children
226
+ }
227
+ end
228
+
177
229
  The result of arrange_serializable can easily be serialized to json with 'to_json', or some other format:
178
230
 
179
231
  TreeNode.arrange_serializable.to_json
@@ -269,10 +321,10 @@ In the example above, the ancestry column is created as a string. This puts a li
269
321
 
270
322
  The materialised path pattern requires Ancestry to use a 'like' condition in order to fetch descendants. This should not be particularly slow however since the the condition never starts with a wildcard which allows the DBMS to use the column index. If you have any data on performance with a large number of records, please drop me line.
271
323
 
272
- = Contributing and licence
324
+ = Contributing and license
273
325
 
274
326
  I will try to keep Ancestry up to date with changing versions of Rails and Ruby and also with any bug reports I might receive. I will implement new features on request as I see fit and have time.
275
327
 
276
328
  Question? Bug report? Faulty/incomplete documentation? Feature request? Please post an issue on 'http://github.com/stefankroes/ancestry/issues'. Make sure you have read the documentation and you have included tests and documentation with any pull request.
277
329
 
278
- Copyright (c) 2013 Stefan Kroes, released under the MIT license
330
+ Copyright (c) 2016 Stefan Kroes, released under the MIT license
@@ -1,3 +1,7 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+ require 'ancestry/version'
4
+
1
5
  Gem::Specification.new do |s|
2
6
  s.name = 'ancestry'
3
7
  s.summary = 'Organize ActiveRecord model into a tree structure'
@@ -11,7 +15,7 @@ Gem::Specification.new do |s|
11
15
  orphaned records.
12
16
  EOF
13
17
 
14
- s.version = '2.1.0'
18
+ s.version = Ancestry::VERSION
15
19
 
16
20
  s.author = 'Stefan Kroes'
17
21
  s.email = 's.a.kroes@gmail.com'
@@ -19,17 +23,22 @@ EOF
19
23
  s.license = 'MIT'
20
24
 
21
25
  s.files = [
22
- 'ancestry.gemspec',
23
- 'init.rb',
24
- 'install.rb',
25
- 'lib/ancestry.rb',
26
- 'lib/ancestry/has_ancestry.rb',
27
- 'lib/ancestry/exceptions.rb',
28
- 'lib/ancestry/class_methods.rb',
29
- 'lib/ancestry/instance_methods.rb',
30
- 'MIT-LICENSE',
26
+ 'ancestry.gemspec',
27
+ 'init.rb',
28
+ 'install.rb',
29
+ 'lib/ancestry.rb',
30
+ 'lib/ancestry/has_ancestry.rb',
31
+ 'lib/ancestry/exceptions.rb',
32
+ 'lib/ancestry/class_methods.rb',
33
+ 'lib/ancestry/instance_methods.rb',
34
+ 'MIT-LICENSE',
31
35
  'README.rdoc'
32
36
  ]
33
37
 
34
- s.add_dependency 'activerecord', '>= 3.0.0'
38
+ s.required_ruby_version = '>= 1.8.7'
39
+ s.add_runtime_dependency 'activerecord', '>= 3.0.0'
40
+ s.add_development_dependency 'rake', '~> 10.0'
41
+ s.add_development_dependency 'test-unit'
42
+ s.add_development_dependency 'minitest'
43
+ s.add_development_dependency 'sqlite3'
35
44
  end
@@ -42,25 +42,34 @@ module Ancestry
42
42
  # Arrange array of nodes into a nested hash of the form
43
43
  # {node => children}, where children = {} if the node has no children
44
44
  def arrange_nodes(nodes)
45
- # Get all nodes ordered by ancestry and start sorting them into an empty hash
46
- nodes.inject(ActiveSupport::OrderedHash.new) do |arranged_nodes, node|
47
- # Find the insertion point for that node by going through its ancestors
48
- node.ancestor_ids.inject(arranged_nodes) do |insertion_point, ancestor_id|
49
- insertion_point.each do |parent, children|
50
- # Change the insertion point to children if node is a descendant of this parent
51
- insertion_point = children if ancestor_id == parent.id
52
- end
53
- insertion_point
54
- end[node] = ActiveSupport::OrderedHash.new
55
- arranged_nodes
45
+ arranged = ActiveSupport::OrderedHash.new
46
+ min_depth = Float::INFINITY
47
+ index = Hash.new { |h, k| h[k] = ActiveSupport::OrderedHash.new }
48
+
49
+ nodes.each do |node|
50
+ children = index[node.id]
51
+ index[node.parent_id][node] = children
52
+
53
+ depth = node.depth
54
+ if depth < min_depth
55
+ min_depth = depth
56
+ arranged.clear
57
+ end
58
+ arranged[node] = children if depth == min_depth
56
59
  end
60
+
61
+ arranged
57
62
  end
58
63
 
59
64
  # Arrangement to nested array
60
- def arrange_serializable options={}, nodes=nil
65
+ def arrange_serializable options={}, nodes=nil, &block
61
66
  nodes = arrange(options) if nodes.nil?
62
67
  nodes.map do |parent, children|
63
- parent.serializable_hash.merge 'children' => arrange_serializable(options, children)
68
+ if block_given?
69
+ yield parent, arrange_serializable(options, children, &block)
70
+ else
71
+ parent.serializable_hash.merge 'children' => arrange_serializable(options, children)
72
+ end
64
73
  end
65
74
  end
66
75
 
@@ -43,8 +43,9 @@ class << ActiveRecord::Base
43
43
  scope :descendants_of, lambda { |object| where(to_node(object).descendant_conditions) }
44
44
  scope :subtree_of, lambda { |object| where(to_node(object).subtree_conditions) }
45
45
  scope :siblings_of, lambda { |object| where(to_node(object).sibling_conditions) }
46
- scope :ordered_by_ancestry, lambda { reorder("(case when #{table_name}.#{ancestry_column} is null then 0 else 1 end), #{table_name}.#{ancestry_column}") }
47
- scope :ordered_by_ancestry_and, lambda { |order| reorder("(case when #{table_name}.#{ancestry_column} is null then 0 else 1 end), #{table_name}.#{ancestry_column}, #{order}") }
46
+ scope :ordered_by_ancestry, lambda { reorder("(CASE WHEN #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)} IS NULL THEN 0 ELSE 1 END), #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}") }
47
+ scope :ordered_by_ancestry_and, lambda { |order| reorder("(CASE WHEN #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)} IS NULL THEN 0 ELSE 1 END), #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}, #{order}") }
48
+ scope :path_of, lambda { |object| to_node(object).path }
48
49
 
49
50
  # Update descendants with new ancestry before save
50
51
  before_save :update_descendants_with_new_ancestry
@@ -74,9 +75,9 @@ class << ActiveRecord::Base
74
75
  }
75
76
  end
76
77
 
77
- after_save :touch_ancestors_callback
78
78
  after_touch :touch_ancestors_callback
79
79
  after_destroy :touch_ancestors_callback
80
+ after_save :touch_ancestors_callback, if: :changed?
80
81
  end
81
82
  end
82
83
 
@@ -86,4 +87,4 @@ ActiveSupport.on_load :active_record do
86
87
  alias_method :acts_as_tree, :has_ancestry
87
88
  end
88
89
  end
89
- end
90
+ end
@@ -53,6 +53,8 @@ module Ancestry
53
53
  descendants.each do |descendant|
54
54
  descendant.without_ancestry_callbacks do
55
55
  new_ancestry = descendant.ancestor_ids.delete_if { |x| x == self.id }.join("/")
56
+ # check for empty string if it's then set to nil
57
+ new_ancestry = nil if new_ancestry.empty?
56
58
  descendant.update_attribute descendant.class.ancestry_column, new_ancestry || nil
57
59
  end
58
60
  end
@@ -92,7 +94,7 @@ module Ancestry
92
94
  end
93
95
 
94
96
  # Ancestors
95
-
97
+
96
98
  def ancestry_changed?
97
99
  changed.include?(self.ancestry_base_class.ancestry_column.to_s)
98
100
  end
@@ -143,8 +145,12 @@ module Ancestry
143
145
  write_attribute self.ancestry_base_class.depth_cache_column, depth
144
146
  end
145
147
 
148
+ def ancestor_of?(node)
149
+ node.ancestor_ids.include?(self.id)
150
+ end
151
+
146
152
  # Parent
147
-
153
+
148
154
  def parent= parent
149
155
  write_attribute(self.ancestry_base_class.ancestry_column, if parent.nil? then nil else parent.child_ancestry end)
150
156
  end
@@ -165,8 +171,12 @@ module Ancestry
165
171
  parent_id.present?
166
172
  end
167
173
 
174
+ def parent_of?(node)
175
+ self.id == node.parent_id
176
+ end
177
+
168
178
  # Root
169
-
179
+
170
180
  def root_id
171
181
  if ancestor_ids.empty? then id else ancestor_ids.first end
172
182
  end
@@ -180,8 +190,12 @@ module Ancestry
180
190
  end
181
191
  alias :root? :is_root?
182
192
 
193
+ def root_of?(node)
194
+ self.id == node.root_id
195
+ end
196
+
183
197
  # Children
184
-
198
+
185
199
  def child_conditions
186
200
  t = get_arel_table
187
201
  t[get_ancestry_column].eq(child_ancestry)
@@ -205,8 +219,12 @@ module Ancestry
205
219
  end
206
220
  alias_method :childless?, :is_childless?
207
221
 
222
+ def child_of?(node)
223
+ self.parent_id == node.id
224
+ end
225
+
208
226
  # Siblings
209
-
227
+
210
228
  def sibling_conditions
211
229
  t = get_arel_table
212
230
  t[get_ancestry_column].eq(read_attribute(self.ancestry_base_class.ancestry_column))
@@ -230,8 +248,12 @@ module Ancestry
230
248
  end
231
249
  alias_method :only_child?, :is_only_child?
232
250
 
251
+ def sibling_of?(node)
252
+ self.ancestry == node.ancestry
253
+ end
254
+
233
255
  # Descendants
234
-
256
+
235
257
  def descendant_conditions
236
258
  t = get_arel_table
237
259
  t[get_ancestry_column].matches("#{child_ancestry}/%").or(t[get_ancestry_column].eq(child_ancestry))
@@ -245,11 +267,15 @@ module Ancestry
245
267
  descendants(depth_options).select(self.ancestry_base_class.primary_key).collect(&self.ancestry_base_class.primary_key.to_sym)
246
268
  end
247
269
 
270
+ def descendant_of?(node)
271
+ ancestor_ids.include?(node.id)
272
+ end
273
+
248
274
  # Subtree
249
-
275
+
250
276
  def subtree_conditions
251
277
  t = get_arel_table
252
- t[get_primary_key_column].eq(self.id).or(t[get_ancestry_column].matches("#{child_ancestry}/%")).or(t[get_ancestry_column].eq(child_ancestry))
278
+ descendant_conditions.or(t[get_primary_key_column].eq(self.id))
253
279
  end
254
280
 
255
281
  def subtree depth_options = {}
@@ -261,7 +287,7 @@ module Ancestry
261
287
  end
262
288
 
263
289
  # Callback disabling
264
-
290
+
265
291
  def without_ancestry_callbacks
266
292
  @disable_ancestry_callbacks = true
267
293
  yield
@@ -269,13 +295,13 @@ module Ancestry
269
295
  end
270
296
 
271
297
  def ancestry_callbacks_disabled?
272
- !!@disable_ancestry_callbacks
298
+ defined?(@disable_ancestry_callbacks) && @disable_ancestry_callbacks
273
299
  end
274
300
 
275
301
  private
276
302
 
277
303
  def cast_primary_key(key)
278
- if [:string, :uuid].include? primary_key_type
304
+ if [:string, :uuid, :text].include? primary_key_type
279
305
  key
280
306
  else
281
307
  key.to_i
@@ -292,9 +318,10 @@ module Ancestry
292
318
  end
293
319
  end
294
320
 
295
- # Validates the ancestry, but can also be applied if validation is bypassed to determine if chidren should be affected
321
+ # Validates the ancestry, but can also be applied if validation is bypassed to determine if children should be affected
296
322
  def sane_ancestry?
297
- ancestry.nil? || (ancestry.to_s =~ Ancestry::ANCESTRY_PATTERN && !ancestor_ids.include?(self.id))
323
+ ancestry_value = read_attribute(self.ancestry_base_class.ancestry_column)
324
+ ancestry_value.nil? || (ancestry_value.to_s =~ Ancestry::ANCESTRY_PATTERN && !ancestor_ids.include?(self.id))
298
325
  end
299
326
 
300
327
  def unscoped_find id
metadata CHANGED
@@ -1,51 +1,108 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ancestry
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Kroes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-16 00:00:00.000000000 Z
11
+ date: 2016-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.0.0
27
- description: ! " Ancestry allows the records of a ActiveRecord model to be organized
28
- in a tree\n structure, using a single, intuitively formatted database column. It
29
- exposes\n all the standard tree structure relations (ancestors, parent, root, children,\n
30
- \ siblings, descendants) and all of them can be fetched in a single sql query.\n
31
- \ Additional features are named_scopes, integrity checking, integrity restoration,\n
32
- \ arrangement of (sub)tree into hashes and different strategies for dealing with\n
33
- \ orphaned records.\n"
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: test-unit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: |2
84
+ Ancestry allows the records of a ActiveRecord model to be organized in a tree
85
+ structure, using a single, intuitively formatted database column. It exposes
86
+ all the standard tree structure relations (ancestors, parent, root, children,
87
+ siblings, descendants) and all of them can be fetched in a single sql query.
88
+ Additional features are named_scopes, integrity checking, integrity restoration,
89
+ arrangement of (sub)tree into hashes and different strategies for dealing with
90
+ orphaned records.
34
91
  email: s.a.kroes@gmail.com
35
92
  executables: []
36
93
  extensions: []
37
94
  extra_rdoc_files: []
38
95
  files:
96
+ - MIT-LICENSE
97
+ - README.rdoc
39
98
  - ancestry.gemspec
40
99
  - init.rb
41
100
  - install.rb
42
101
  - lib/ancestry.rb
43
- - lib/ancestry/has_ancestry.rb
44
- - lib/ancestry/exceptions.rb
45
102
  - lib/ancestry/class_methods.rb
103
+ - lib/ancestry/exceptions.rb
104
+ - lib/ancestry/has_ancestry.rb
46
105
  - lib/ancestry/instance_methods.rb
47
- - MIT-LICENSE
48
- - README.rdoc
49
106
  homepage: http://github.com/stefankroes/ancestry
50
107
  licenses:
51
108
  - MIT
@@ -56,19 +113,18 @@ require_paths:
56
113
  - lib
57
114
  required_ruby_version: !ruby/object:Gem::Requirement
58
115
  requirements:
59
- - - ! '>='
116
+ - - ">="
60
117
  - !ruby/object:Gem::Version
61
- version: '0'
118
+ version: 1.8.7
62
119
  required_rubygems_version: !ruby/object:Gem::Requirement
63
120
  requirements:
64
- - - ! '>='
121
+ - - ">="
65
122
  - !ruby/object:Gem::Version
66
123
  version: '0'
67
124
  requirements: []
68
125
  rubyforge_project:
69
- rubygems_version: 2.1.11
126
+ rubygems_version: 2.5.1
70
127
  signing_key:
71
128
  specification_version: 4
72
129
  summary: Organize ActiveRecord model into a tree structure
73
130
  test_files: []
74
- has_rdoc: