familyable 0.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +82 -0
- data/Rakefile +21 -0
- data/lib/familyable/concerns/relationships.rb +258 -0
- data/lib/familyable/version.rb +3 -0
- data/lib/familyable.rb +3 -0
- data/lib/generators/familyable/generator.rb +54 -0
- data/lib/generators/familyable/relationships_generator.rb +23 -0
- data/lib/tasks/familyable.rake +4 -0
- metadata +94 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c05a813418d27a79b6a38a33d303ad1bd02e551d
|
4
|
+
data.tar.gz: 275d41cb50d00fb8f0a3512e712fb0fa979f9593
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ef6d2919bc506784be2d4b4b8770817994f10bebf506e2e0d3bdc1e41875444c6d41cfde7d04c87880efe02e15bd0f803efbd07c0273bbe5d8fdf78eeb1ea61a
|
7
|
+
data.tar.gz: b0bf6eb658ef5b07c1f802900f7db5a176c1edbd20be0e5916f75401551b9a763612b2fc534ed1d30efaffdadc1934b024dc2f4c234deb82dd33ca0beaa64c72
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 YOURNAME
|
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.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
### Familyable
|
2
|
+
|
3
|
+
This gem makes creating self-referential parent child relationships on a model easy. So for a `Person` model you have `person.parent` and `person.children` where the parent and children are also people.
|
4
|
+
|
5
|
+
You also get the following instance methods:
|
6
|
+
|
7
|
+
* descendents
|
8
|
+
* elders
|
9
|
+
* siblings
|
10
|
+
* family
|
11
|
+
* master *- the 'oldest' in the family*
|
12
|
+
|
13
|
+
and the class method:
|
14
|
+
|
15
|
+
* masters *- everyone without a parent*
|
16
|
+
|
17
|
+
Standard stuff I know but...
|
18
|
+
##### Everyone of the methods above works with a single call to the data base!!!
|
19
|
+
|
20
|
+
This is a **[huge](https://github.com/brookisme/familyable-testapp)** performance gain. In fact, being able build the above methods with a single database call was the entire motivation for gemifiying something that otherwise was entirely straight forward. It should be noted that this was built the day after reading [this](http://hashrocket.com/blog/posts/recursive-sql-in-activerecord).
|
21
|
+
|
22
|
+
-----------------------------------------------------------
|
23
|
+
|
24
|
+
##### WARNING: This project is still in development
|
25
|
+
[x] create relationship concern
|
26
|
+
[X] create generators for relationship models
|
27
|
+
[X] check that it works with engines
|
28
|
+
[ ] generate data for testapp
|
29
|
+
[ ] tests tests tests
|
30
|
+
[ ] refactor concern
|
31
|
+
[ ] add babies methods (class and instance)?
|
32
|
+
|
33
|
+
|
34
|
+
### Requirments
|
35
|
+
|
36
|
+
You must be using a postgres data base... thats where the single-db-query magic happens.
|
37
|
+
|
38
|
+
### Installation
|
39
|
+
|
40
|
+
familyable gem will be comming soon for now get it from this repo.. actually its too soon to use it - but soon!!!
|
41
|
+
|
42
|
+
### Usage
|
43
|
+
|
44
|
+
-----------------------------------------------------------
|
45
|
+
|
46
|
+
Example: Adding Relationships to an existing `Person` model:
|
47
|
+
|
48
|
+
##### Step 1: Generate Relationship Model
|
49
|
+
|
50
|
+
```
|
51
|
+
$ bundle exec rails g familyable:relationships Person
|
52
|
+
$ bundle exec rake db:migrate
|
53
|
+
```
|
54
|
+
|
55
|
+
Note: For use with Rails Engines use the full model name from the the root of your Engine directory.
|
56
|
+
|
57
|
+
```
|
58
|
+
$ bundle exec rails g familyable:relationships MyEngine::Person
|
59
|
+
```
|
60
|
+
|
61
|
+
|
62
|
+
##### Step 2: Add Relationships Concern to Model
|
63
|
+
|
64
|
+
_app/models/person.rb_
|
65
|
+
```ruby
|
66
|
+
class Person < ActiveRecord::Base
|
67
|
+
include Familyable::Relationships
|
68
|
+
...
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
##### Step 3: You're done! start coding
|
73
|
+
|
74
|
+
quick note: all the instance methods above (accept for master) take an optional parameter *include\_self=false*. it does what you exactly what you think.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
Person.masters
|
78
|
+
person.master
|
79
|
+
person.descendents
|
80
|
+
person.descendents(true)
|
81
|
+
...
|
82
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Familyable'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
@@ -0,0 +1,258 @@
|
|
1
|
+
module Familyable
|
2
|
+
module Relationships
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
included do
|
8
|
+
has_many relationships_name.to_sym
|
9
|
+
has_many :children, through: relationships_name.to_sym
|
10
|
+
has_one inv_relationships_name.to_sym, class_name: relationship_class_name, foreign_key: "child_id"
|
11
|
+
has_one :parent, through: inv_relationships_name.to_sym, source: model_name.to_sym
|
12
|
+
end
|
13
|
+
|
14
|
+
# *****************************
|
15
|
+
#
|
16
|
+
# Main Interface
|
17
|
+
#
|
18
|
+
# *****************************
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
def masters
|
22
|
+
where(without_parents_where_sql)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def master
|
27
|
+
call = elders
|
28
|
+
call.where(klass.without_parents_where_sql).first
|
29
|
+
end
|
30
|
+
|
31
|
+
def descendents include_self=false
|
32
|
+
query_call(
|
33
|
+
"#{table_name}.id IN (#{descendents_sql_list})",
|
34
|
+
include_self
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def elders include_self=false
|
39
|
+
query_call(
|
40
|
+
"#{table_name}.id IN (#{elders_sql_list})",
|
41
|
+
include_self
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def siblings include_self=false
|
46
|
+
query_call(
|
47
|
+
"#{table_name}.id IN (#{siblings_sql_list})",
|
48
|
+
include_self
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def family include_self=false
|
53
|
+
query_call(
|
54
|
+
"#{table_name}.id IN (#{family_sql_list})",
|
55
|
+
include_self
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
# *****************************
|
60
|
+
#
|
61
|
+
# Utilities
|
62
|
+
#
|
63
|
+
# *****************************
|
64
|
+
|
65
|
+
module ClassMethods
|
66
|
+
|
67
|
+
#
|
68
|
+
# ID LISTS
|
69
|
+
#
|
70
|
+
|
71
|
+
def children_of(id_sql)
|
72
|
+
id_sql = safe_identifier(id_sql)
|
73
|
+
tree_sql = <<-SQL
|
74
|
+
SELECT DISTINCT #{relationship_table_name}.child_id
|
75
|
+
FROM #{table_name}
|
76
|
+
JOIN #{relationship_table_name}
|
77
|
+
ON #{table_name}.id = #{relationship_table_name}.#{parent_field_name}
|
78
|
+
WHERE #{table_name}.id = #{id_sql}
|
79
|
+
SQL
|
80
|
+
end
|
81
|
+
|
82
|
+
def descendents_of(id_sql)
|
83
|
+
id_sql = safe_identifier(id_sql)
|
84
|
+
tree_sql = <<-SQL
|
85
|
+
WITH RECURSIVE search_tree(id, path) AS (
|
86
|
+
SELECT id, ARRAY[id]
|
87
|
+
FROM #{table_name}
|
88
|
+
WHERE id = #{id_sql}
|
89
|
+
UNION ALL
|
90
|
+
SELECT #{table_name}.id, path || #{table_name}.id
|
91
|
+
FROM search_tree
|
92
|
+
JOIN #{relationship_table_name} ON #{relationship_table_name}.#{parent_field_name} = search_tree.id
|
93
|
+
JOIN #{table_name} ON #{table_name}.id = #{relationship_table_name}.child_id
|
94
|
+
WHERE NOT #{table_name}.id = ANY(path)
|
95
|
+
)
|
96
|
+
SELECT id FROM search_tree ORDER BY path
|
97
|
+
SQL
|
98
|
+
end
|
99
|
+
|
100
|
+
def elders_of(id_sql)
|
101
|
+
id_sql = safe_identifier(id_sql)
|
102
|
+
tree_sql = <<-SQL
|
103
|
+
WITH RECURSIVE search_tree(id, path) AS (
|
104
|
+
SELECT id, ARRAY[id]
|
105
|
+
FROM #{table_name}
|
106
|
+
WHERE id = #{id_sql}
|
107
|
+
UNION ALL
|
108
|
+
SELECT #{table_name}.id, path || #{table_name}.id
|
109
|
+
FROM search_tree
|
110
|
+
JOIN #{relationship_table_name} ON #{relationship_table_name}.child_id = search_tree.id
|
111
|
+
JOIN #{table_name} ON #{table_name}.id = #{relationship_table_name}.#{parent_field_name}
|
112
|
+
WHERE NOT #{table_name}.id = ANY(path)
|
113
|
+
)
|
114
|
+
SELECT id FROM search_tree ORDER BY path
|
115
|
+
SQL
|
116
|
+
end
|
117
|
+
|
118
|
+
def without_parents_where_sql
|
119
|
+
"#{table_name}.id NOT IN (
|
120
|
+
SELECT DISTINCT #{relationship_table_name}.child_id
|
121
|
+
FROM #{relationship_table_name}
|
122
|
+
)"
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# UTILS
|
127
|
+
#
|
128
|
+
|
129
|
+
def relationship_table_name
|
130
|
+
if @relationship_table_name.nil?
|
131
|
+
@relationship_table_name = "#{table_name.singularize}_relationships"
|
132
|
+
end
|
133
|
+
@relationship_table_name
|
134
|
+
end
|
135
|
+
|
136
|
+
def relationship_class_name
|
137
|
+
if @relationship_class_name.nil?
|
138
|
+
@relationship_class_name = "#{self.name.split("::").last}Relationship"
|
139
|
+
end
|
140
|
+
@relationship_class_name
|
141
|
+
end
|
142
|
+
|
143
|
+
def model_name
|
144
|
+
if @model_name.nil?
|
145
|
+
@model_name = "#{self.name.split("::").last.downcase}"
|
146
|
+
end
|
147
|
+
@model_name
|
148
|
+
end
|
149
|
+
|
150
|
+
def relationships_name
|
151
|
+
if @relationships_name.nil?
|
152
|
+
@relationships_name = "#{self.name.split("::").last.downcase}_relationships"
|
153
|
+
end
|
154
|
+
@relationships_name
|
155
|
+
end
|
156
|
+
|
157
|
+
def inv_relationships_name
|
158
|
+
if @inv_relationships_name.nil?
|
159
|
+
@inv_relationships_name = "inverse_#{relationships_name}"
|
160
|
+
end
|
161
|
+
@inv_relationships_name
|
162
|
+
end
|
163
|
+
|
164
|
+
def parent_field_name
|
165
|
+
if @parent_field_name.nil?
|
166
|
+
@parent_field_name = "#{self.name.split("::").last.downcase}_id"
|
167
|
+
end
|
168
|
+
@parent_field_name
|
169
|
+
end
|
170
|
+
|
171
|
+
def safe_identifier id_sql
|
172
|
+
if id_sql.to_i == 0
|
173
|
+
"(#{id_sql})"
|
174
|
+
else
|
175
|
+
id_sql
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
private
|
182
|
+
|
183
|
+
#
|
184
|
+
# SQL LISTS
|
185
|
+
#
|
186
|
+
|
187
|
+
def descendents_sql_list
|
188
|
+
klass.descendents_of(id)
|
189
|
+
end
|
190
|
+
|
191
|
+
def elders_sql_list
|
192
|
+
klass.elders_of(id)
|
193
|
+
end
|
194
|
+
|
195
|
+
def siblings_sql_list
|
196
|
+
klass.children_of(select_parent_sql)
|
197
|
+
end
|
198
|
+
|
199
|
+
def family_sql_list
|
200
|
+
klass.descendents_of(select_master_sql)
|
201
|
+
end
|
202
|
+
|
203
|
+
#
|
204
|
+
# SQL
|
205
|
+
#
|
206
|
+
|
207
|
+
def select_parent_sql
|
208
|
+
"SELECT #{relationship_table_name}.#{parent_field_name}
|
209
|
+
FROM #{klass.table_name}
|
210
|
+
JOIN #{relationship_table_name}
|
211
|
+
ON #{klass.table_name}.id = #{relationship_table_name}.#{parent_field_name}
|
212
|
+
WHERE #{relationship_table_name}.child_id = #{id}
|
213
|
+
LIMIT 1"
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
def select_master_sql
|
218
|
+
select_from_sql_list_and(klass.elders_of(id),klass.without_parents_where_sql)
|
219
|
+
end
|
220
|
+
|
221
|
+
#
|
222
|
+
# Utils
|
223
|
+
#
|
224
|
+
|
225
|
+
def query_call(where_sql,include_self=false)
|
226
|
+
call = self.class.where(where_sql)
|
227
|
+
call = call.where.not(id: id) unless include_self
|
228
|
+
call
|
229
|
+
end
|
230
|
+
|
231
|
+
def klass
|
232
|
+
@klass ||= self.class
|
233
|
+
end
|
234
|
+
|
235
|
+
def table_name
|
236
|
+
@table_name ||= klass.table_name
|
237
|
+
end
|
238
|
+
|
239
|
+
def relationship_table_name
|
240
|
+
@relationship_table_name ||= klass.relationship_table_name
|
241
|
+
end
|
242
|
+
|
243
|
+
def parent_field_name
|
244
|
+
@parent_field_name ||= klass.parent_field_name
|
245
|
+
end
|
246
|
+
|
247
|
+
def select_from_sql_list_and(sql_list,and_sql)
|
248
|
+
"SELECT #{klass.table_name}.id FROM #{klass.table_name}
|
249
|
+
WHERE (
|
250
|
+
#{klass.table_name}.id IN (
|
251
|
+
#{sql_list}
|
252
|
+
)
|
253
|
+
) AND (
|
254
|
+
#{and_sql}
|
255
|
+
)"
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
data/lib/familyable.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module Familyable
|
3
|
+
class Generator < Rails::Generators::Base
|
4
|
+
desc "Shared options and methods for Familyable Generators"
|
5
|
+
|
6
|
+
argument :model_name, type: :string, required: true, desc: "model name"
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def model_class_name
|
11
|
+
@model_name.camelize
|
12
|
+
end
|
13
|
+
|
14
|
+
def clean_model_class_name
|
15
|
+
model_class_name.split("::").last
|
16
|
+
end
|
17
|
+
|
18
|
+
def engine_name
|
19
|
+
parts = model_class_name.split("::")
|
20
|
+
if parts.length > 1
|
21
|
+
parts.pop()
|
22
|
+
parts.join("::")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def model_base_name
|
27
|
+
@model_name.underscore
|
28
|
+
end
|
29
|
+
|
30
|
+
def clean_model_base_name
|
31
|
+
model_base_name.split("/").last
|
32
|
+
end
|
33
|
+
|
34
|
+
def relationship_class_name
|
35
|
+
"#{model_class_name}Relationship"
|
36
|
+
end
|
37
|
+
|
38
|
+
def clean_relationship_class_name
|
39
|
+
"#{clean_model_class_name}Relationship"
|
40
|
+
end
|
41
|
+
|
42
|
+
def app_root_path
|
43
|
+
if engine_name.nil?
|
44
|
+
"#{Rails.root}"
|
45
|
+
else
|
46
|
+
"#{engine_name.constantize::Engine.root}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def relationship_model_path
|
51
|
+
"#{app_root_path}/app/models/#{relationship_class_name.underscore}.rb"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'generator')
|
2
|
+
module Familyable
|
3
|
+
class RelationshipsGenerator < Familyable::Generator
|
4
|
+
desc "Options and methods for Familyable::Relationship"
|
5
|
+
|
6
|
+
argument :model_name, type: :string, required: true, desc: "model name"
|
7
|
+
class_option :delete, type: :boolean, required: false, default: false, desc: "delete relationship for model: defaut=false"
|
8
|
+
|
9
|
+
def generate_relationships
|
10
|
+
if options[:delete]
|
11
|
+
system("bundle exec rails d model #{clean_relationship_class_name}")
|
12
|
+
else
|
13
|
+
generate "model", "#{clean_relationship_class_name} #{clean_model_base_name}:references child:references"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_class_name
|
18
|
+
unless options[:delete]
|
19
|
+
gsub_file(relationship_model_path, "belongs_to :child", "belongs_to :child, class_name:\"#{clean_model_class_name}\"")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: familyable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brook Williams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pg
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-rails
|
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
|
+
description: A gem for creating self-referential parent child relationships on a model
|
56
|
+
email:
|
57
|
+
- brook.williams@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- MIT-LICENSE
|
63
|
+
- README.md
|
64
|
+
- Rakefile
|
65
|
+
- lib/familyable.rb
|
66
|
+
- lib/familyable/concerns/relationships.rb
|
67
|
+
- lib/familyable/version.rb
|
68
|
+
- lib/generators/familyable/generator.rb
|
69
|
+
- lib/generators/familyable/relationships_generator.rb
|
70
|
+
- lib/tasks/familyable.rake
|
71
|
+
homepage: http://stickandlogdesigns.com
|
72
|
+
licenses: []
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 2.2.2
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
93
|
+
summary: A gem for creating self-referential parent child relationships on a model
|
94
|
+
test_files: []
|