genealogy 0.0.2.beta1
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.
- data/lib/genealogy.rb +10 -0
- data/lib/genealogy/constants.rb +3 -0
- data/lib/genealogy/exceptions.rb +13 -0
- data/lib/genealogy/genealogy.rb +67 -0
- data/lib/genealogy/linking_methods.rb +192 -0
- data/lib/genealogy/query_methods.rb +113 -0
- data/lib/genealogy/spouse_methods.rb +32 -0
- data/lib/genealogy/version.rb +3 -0
- metadata +150 -0
data/lib/genealogy.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'genealogy/constants')
|
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'genealogy/exceptions')
|
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'genealogy/query_methods')
|
|
4
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'genealogy/linking_methods')
|
|
5
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'genealogy/spouse_methods')
|
|
6
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'genealogy/genealogy')
|
|
7
|
+
|
|
8
|
+
ActiveRecord::Base.send :extend, Genealogy
|
|
9
|
+
|
|
10
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Genealogy
|
|
2
|
+
class WrongArgumentException < RuntimeError; end
|
|
3
|
+
class WrongOptionException < RuntimeError; end
|
|
4
|
+
class WrongOptionValueException < RuntimeError; end
|
|
5
|
+
class LineageGapException < RuntimeError; end
|
|
6
|
+
class IncompatibleObjectException < RuntimeError; end
|
|
7
|
+
class WrongSexException < RuntimeError; end
|
|
8
|
+
class IncompatibleRelationshipException < RuntimeError
|
|
9
|
+
def initialize(msg = "Trying to create a relationship incopatible with the the existing ones")
|
|
10
|
+
super(msg)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Genealogy
|
|
2
|
+
|
|
3
|
+
def check_options(options, admitted_keys)
|
|
4
|
+
|
|
5
|
+
raise WrongArgumentException, "first argument must be in a hash." unless options.is_a? Hash
|
|
6
|
+
raise WrongArgumentException, "seconf argument must be in an array." unless admitted_keys.is_a? Array
|
|
7
|
+
|
|
8
|
+
options.each do |key, value|
|
|
9
|
+
unless admitted_keys.include? key
|
|
10
|
+
raise WrongOptionException.new("Unknown option: #{key.inspect} => #{value.inspect}.")
|
|
11
|
+
end
|
|
12
|
+
if block_given?
|
|
13
|
+
yield key, value
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def has_parents options = {}
|
|
21
|
+
|
|
22
|
+
admitted_keys = [:sex_column, :sex_values, :father_column, :mother_column, :spouse_column, :spouse]
|
|
23
|
+
check_options(options, admitted_keys) do |key, value|
|
|
24
|
+
if key == :sex_values
|
|
25
|
+
raise WrongOptionException, ":sex_values option must be an array with two char: first for male sex symbol an last for female" unless value.is_a?(Array) and value.size == 2 and value.first.to_s.size == 1 and value.last.to_s.size == 1
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class_attribute :spouse_enabled
|
|
30
|
+
self.spouse_enabled = options[:spouse].try(:==,true) || false
|
|
31
|
+
tracked_parents = [:father, :mother]
|
|
32
|
+
tracked_parents << :spouse if spouse_enabled
|
|
33
|
+
|
|
34
|
+
## sex
|
|
35
|
+
# class attributes
|
|
36
|
+
class_attribute :sex_column, :sex_values, :sex_male_value, :sex_female_value
|
|
37
|
+
self.sex_column = options[:sex_column] || :sex
|
|
38
|
+
self.sex_values = (options[:sex_values] and options[:sex_values].to_a.map(&:to_s)) || ['M','F']
|
|
39
|
+
self.sex_male_value = self.sex_values.first
|
|
40
|
+
self.sex_female_value = self.sex_values.last
|
|
41
|
+
# instance attribute
|
|
42
|
+
alias_attribute :sex, sex_column if self.sex_column != :sex
|
|
43
|
+
# validation
|
|
44
|
+
validates_presence_of sex_column
|
|
45
|
+
validates_format_of sex_column, :with => /[#{sex_values.join}]/
|
|
46
|
+
|
|
47
|
+
## relatives associations
|
|
48
|
+
tracked_parents.each do |key|
|
|
49
|
+
# class attribute where is stored the correspondig foreign_key column name
|
|
50
|
+
class_attribute_name = "#{key}_column"
|
|
51
|
+
foreign_key = "#{key}_id"
|
|
52
|
+
class_attribute class_attribute_name
|
|
53
|
+
self.send("#{class_attribute_name}=", options[class_attribute_name.to_sym] || foreign_key)
|
|
54
|
+
|
|
55
|
+
# self join association
|
|
56
|
+
attr_accessible foreign_key
|
|
57
|
+
belongs_to key, class_name: self, foreign_key: foreign_key
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Include instance methods and class methods
|
|
62
|
+
include Genealogy::QueryMethods
|
|
63
|
+
include Genealogy::LinkingMethods
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
module Genealogy
|
|
2
|
+
module LinkingMethods
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
# parents
|
|
6
|
+
[:father, :mother].each do |parent|
|
|
7
|
+
|
|
8
|
+
# add method
|
|
9
|
+
define_method "add_#{parent}" do |relative|
|
|
10
|
+
unless relative.nil?
|
|
11
|
+
raise IncompatibleObjectException, "Linked objects must be instances of the same class: got #{relative.class} for #{self.class}" unless relative.is_a? self.class
|
|
12
|
+
incompatible_parents = self.offspring | self.siblings.to_a | [self]
|
|
13
|
+
raise IncompatibleRelationshipException, "#{relative} can't be #{parent} of #{self}" if incompatible_parents.include? relative
|
|
14
|
+
raise WrongSexException, "Can't add a #{relative.sex} #{parent}" unless (parent == :father and relative.is_male?) or (parent == :mother and relative.is_female?)
|
|
15
|
+
end
|
|
16
|
+
self.send("#{parent}=",relative)
|
|
17
|
+
save!
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# remove method
|
|
21
|
+
define_method "remove_#{parent}" do
|
|
22
|
+
self.send("#{parent}=",nil)
|
|
23
|
+
save!
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# add both
|
|
29
|
+
def add_parents(father,mother)
|
|
30
|
+
transaction do
|
|
31
|
+
add_father(father)
|
|
32
|
+
add_mother(mother)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# remove both
|
|
37
|
+
def remove_parents
|
|
38
|
+
transaction do
|
|
39
|
+
remove_father
|
|
40
|
+
remove_mother
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# grandparents
|
|
45
|
+
[:father, :mother].each do |parent|
|
|
46
|
+
[:father, :mother].each do |grandparent|
|
|
47
|
+
# add one
|
|
48
|
+
define_method "add_#{Genealogy::LINEAGE_NAME[parent]}_grand#{grandparent}" do |relative|
|
|
49
|
+
raise IncompatibleRelationshipException, "#{self} can't be grand#{grandparent} of itself" if relative == self
|
|
50
|
+
raise_if_gap_on(parent)
|
|
51
|
+
send(parent).send("add_#{grandparent}",relative)
|
|
52
|
+
end
|
|
53
|
+
# remove one
|
|
54
|
+
define_method "remove_#{Genealogy::LINEAGE_NAME[parent]}_grand#{grandparent}" do
|
|
55
|
+
raise_if_gap_on(parent)
|
|
56
|
+
send(parent).send("remove_#{grandparent}")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
[:father, :mother].each do |parent|
|
|
62
|
+
# add two by lineage
|
|
63
|
+
define_method "add_#{Genealogy::LINEAGE_NAME[parent]}_grandparents" do |grandfather,grandmother|
|
|
64
|
+
raise_if_gap_on(parent)
|
|
65
|
+
send(parent).send("add_parents",grandfather,grandmother)
|
|
66
|
+
end
|
|
67
|
+
# remove two by lineage
|
|
68
|
+
define_method "remove_#{Genealogy::LINEAGE_NAME[parent]}_grandparents" do
|
|
69
|
+
raise_if_gap_on(parent)
|
|
70
|
+
send(parent).send("remove_parents")
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# add all
|
|
75
|
+
def add_grandparents(pgf,pgm,mgf,mgm)
|
|
76
|
+
transaction do
|
|
77
|
+
add_paternal_grandparents(pgf,pgm)
|
|
78
|
+
add_maternal_grandparents(mgf,mgm)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# remove all
|
|
83
|
+
def remove_grandparents
|
|
84
|
+
transaction do
|
|
85
|
+
remove_paternal_grandparents
|
|
86
|
+
remove_maternal_grandparents
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
## siblings
|
|
92
|
+
def add_siblings(*args)
|
|
93
|
+
options = args.extract_options!
|
|
94
|
+
raise LineageGapException, "Can't add siblings if both parents are nil" unless father and mother
|
|
95
|
+
raise IncompatibleRelationshipException, "Can't add an ancestor as sibling" unless (ancestors.to_a & args).empty?
|
|
96
|
+
transaction do
|
|
97
|
+
args.each do |sib|
|
|
98
|
+
case options[:half]
|
|
99
|
+
when :father
|
|
100
|
+
sib.add_father(self.father)
|
|
101
|
+
sib.add_mother(options[:spouse]) if options[:spouse]
|
|
102
|
+
when :mother
|
|
103
|
+
sib.add_father(options[:spouse]) if options[:spouse]
|
|
104
|
+
sib.add_mother(self.mother)
|
|
105
|
+
when nil
|
|
106
|
+
sib.add_father(self.father)
|
|
107
|
+
sib.add_mother(self.mother)
|
|
108
|
+
else
|
|
109
|
+
raise WrongOptionValueException, "Admitted values for :half options are: :father, :mother or nil"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def remove_siblings(options = {})
|
|
116
|
+
options.delete_if{ |key,value| key == :half and ![:father,:mother].include?(value) }
|
|
117
|
+
|
|
118
|
+
resulting_indivs = siblings(options)
|
|
119
|
+
|
|
120
|
+
transaction do
|
|
121
|
+
|
|
122
|
+
resulting_indivs.each do |sib|
|
|
123
|
+
case options[:half]
|
|
124
|
+
when :father
|
|
125
|
+
sib.remove_father
|
|
126
|
+
sib.remove_mother if options[:affect_spouse] == true
|
|
127
|
+
when :mother
|
|
128
|
+
sib.remove_father if options[:affect_spouse] == true
|
|
129
|
+
sib.remove_mother
|
|
130
|
+
when nil
|
|
131
|
+
sib.remove_parents
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# offspring
|
|
140
|
+
def add_offspring(*args)
|
|
141
|
+
options = args.extract_options!
|
|
142
|
+
|
|
143
|
+
raise_if_sex_undefined
|
|
144
|
+
|
|
145
|
+
transaction do
|
|
146
|
+
args.each do |child|
|
|
147
|
+
case sex
|
|
148
|
+
when sex_male_value
|
|
149
|
+
child.add_father(self)
|
|
150
|
+
child.add_mother(options[:spouse]) if options[:spouse]
|
|
151
|
+
when sex_female_value
|
|
152
|
+
child.add_father(options[:spouse]) if options[:spouse]
|
|
153
|
+
child.add_mother(self)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def remove_offspring(options = {})
|
|
160
|
+
|
|
161
|
+
raise_if_sex_undefined
|
|
162
|
+
|
|
163
|
+
resulting_indivs = offspring(options)
|
|
164
|
+
transaction do
|
|
165
|
+
resulting_indivs.each do |child|
|
|
166
|
+
if options[:affect_spouse] == true
|
|
167
|
+
child.remove_parents
|
|
168
|
+
else
|
|
169
|
+
case sex
|
|
170
|
+
when sex_male_value
|
|
171
|
+
child.remove_father
|
|
172
|
+
when sex_female_value
|
|
173
|
+
child.remove_mother
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
resulting_indivs.empty? ? false : true
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
private
|
|
182
|
+
|
|
183
|
+
def raise_if_gap_on(relative)
|
|
184
|
+
raise LineageGapException, "#{self} doesn't have #{relative}" unless send(relative)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def raise_if_sex_undefined
|
|
188
|
+
raise WrongSexException, "Can't proceed if sex undefined for #{self}" unless is_male? or is_female?
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
module Genealogy
|
|
2
|
+
module QueryMethods
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
# parents
|
|
6
|
+
def parents
|
|
7
|
+
if father or mother
|
|
8
|
+
[father,mother]
|
|
9
|
+
else
|
|
10
|
+
[]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# grandparents
|
|
15
|
+
[:father, :mother].each do |parent|
|
|
16
|
+
[:father, :mother].each do |grandparent|
|
|
17
|
+
|
|
18
|
+
# get one
|
|
19
|
+
define_method "#{Genealogy::LINEAGE_NAME[parent]}_grand#{grandparent}" do
|
|
20
|
+
send(parent) && send(parent).send(grandparent)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# get two by lineage
|
|
26
|
+
define_method "#{Genealogy::LINEAGE_NAME[parent]}_grandparents" do
|
|
27
|
+
(send(parent) && send(parent).parents) || []
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# get all
|
|
33
|
+
def grandparents
|
|
34
|
+
result = []
|
|
35
|
+
[:father, :mother].each do |parent|
|
|
36
|
+
[:father, :mother].each do |grandparent|
|
|
37
|
+
result << send("#{Genealogy::LINEAGE_NAME[parent]}_grand#{grandparent}")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
result.compact! if result.all?{|gp| gp.nil? }
|
|
41
|
+
result
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def offspring(options = {})
|
|
45
|
+
|
|
46
|
+
if spouse = options[:spouse]
|
|
47
|
+
raise WrongSexException, "Something wrong with spouse #{spouse} gender." if spouse.sex == sex
|
|
48
|
+
end
|
|
49
|
+
case sex
|
|
50
|
+
when sex_male_value
|
|
51
|
+
self.class.find_all_by_father_id(id, :conditions => (["mother_id == ?", spouse.id] if spouse) )
|
|
52
|
+
when sex_female_value
|
|
53
|
+
self.class.find_all_by_mother_id(id, :conditions => (["father_id == ?", spouse.id] if spouse) )
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def siblings(options = {})
|
|
58
|
+
result = case options[:half]
|
|
59
|
+
when :father # common father
|
|
60
|
+
father.try(:offspring, options).to_a
|
|
61
|
+
when :mother # common mother
|
|
62
|
+
mother.try(:offspring, options).to_a
|
|
63
|
+
when nil # exluding half siblings
|
|
64
|
+
siblings(:half => :father) & siblings(:half => :mother)
|
|
65
|
+
when :only # only half siblings
|
|
66
|
+
siblings(:half => :include) - siblings
|
|
67
|
+
when :include # including half siblings
|
|
68
|
+
siblings(:half => :father) | siblings(:half => :mother)
|
|
69
|
+
else
|
|
70
|
+
raise WrongOptionValueException, "Admitted values for :half options are: :father, :mother, false, true or nil"
|
|
71
|
+
end
|
|
72
|
+
result - [self]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def half_siblings(options = {})
|
|
76
|
+
siblings(:half => :only)
|
|
77
|
+
# todo: inprove with option :father and :mother
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def ancestors
|
|
81
|
+
result = []
|
|
82
|
+
remaining = parents.to_a.compact
|
|
83
|
+
until remaining.empty?
|
|
84
|
+
result << remaining.shift
|
|
85
|
+
remaining += result.last.parents.to_a.compact
|
|
86
|
+
end
|
|
87
|
+
result.uniq
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def descendants
|
|
91
|
+
result = []
|
|
92
|
+
remaining = offspring.to_a.compact
|
|
93
|
+
until remaining.empty?
|
|
94
|
+
result << remaining.shift
|
|
95
|
+
remaining += result.last.offspring.to_a.compact
|
|
96
|
+
end
|
|
97
|
+
result.uniq
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def is_female?
|
|
102
|
+
sex == sex_female_value
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def is_male?
|
|
106
|
+
sex == sex_male_value
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
module ClassMethods
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Genealogy
|
|
2
|
+
module SpouseMethods
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
# add method
|
|
6
|
+
def add_spouse(obj)
|
|
7
|
+
raise IncompatibleObjectException, "Linked objects must be instances of the same class" unless obj.is_a? self.class
|
|
8
|
+
raise WrongSexException, "Can't add spouse with same sex" if self.sex == obj.sex
|
|
9
|
+
self.spouse = obj
|
|
10
|
+
obj.spouse = self
|
|
11
|
+
transaction do
|
|
12
|
+
obj.save!
|
|
13
|
+
save!
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# remove method
|
|
18
|
+
def remove_spouse
|
|
19
|
+
transaction do
|
|
20
|
+
ex_spouse = spouse
|
|
21
|
+
spouse.spouse = nil
|
|
22
|
+
self.spouse = nil
|
|
23
|
+
ex_spouse.save!
|
|
24
|
+
save!
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
module ClassMethods
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: genealogy
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2.beta1
|
|
5
|
+
prerelease: 6
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- masciugo
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2013-05-21 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: activerecord
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ! '>='
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '0'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: activesupport
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ! '>='
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
38
|
+
type: :runtime
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: sqlite3
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ! '>='
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
- !ruby/object:Gem::Dependency
|
|
63
|
+
name: rake
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
66
|
+
requirements:
|
|
67
|
+
- - ! '>='
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
type: :development
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
78
|
+
- !ruby/object:Gem::Dependency
|
|
79
|
+
name: rspec
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
82
|
+
requirements:
|
|
83
|
+
- - ! '>='
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
86
|
+
type: :development
|
|
87
|
+
prerelease: false
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ! '>='
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
94
|
+
- !ruby/object:Gem::Dependency
|
|
95
|
+
name: debugger
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
97
|
+
none: false
|
|
98
|
+
requirements:
|
|
99
|
+
- - ! '>='
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '0'
|
|
102
|
+
type: :development
|
|
103
|
+
prerelease: false
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ! '>='
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
description: a description
|
|
111
|
+
email:
|
|
112
|
+
- masciugo@gmail.com
|
|
113
|
+
executables: []
|
|
114
|
+
extensions: []
|
|
115
|
+
extra_rdoc_files: []
|
|
116
|
+
files:
|
|
117
|
+
- lib/genealogy.rb
|
|
118
|
+
- lib/genealogy/constants.rb
|
|
119
|
+
- lib/genealogy/exceptions.rb
|
|
120
|
+
- lib/genealogy/genealogy.rb
|
|
121
|
+
- lib/genealogy/linking_methods.rb
|
|
122
|
+
- lib/genealogy/query_methods.rb
|
|
123
|
+
- lib/genealogy/spouse_methods.rb
|
|
124
|
+
- lib/genealogy/version.rb
|
|
125
|
+
homepage: https://github.com//genealogy
|
|
126
|
+
licenses:
|
|
127
|
+
- MIT
|
|
128
|
+
post_install_message:
|
|
129
|
+
rdoc_options: []
|
|
130
|
+
require_paths:
|
|
131
|
+
- lib
|
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
|
+
none: false
|
|
134
|
+
requirements:
|
|
135
|
+
- - ! '>='
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '0'
|
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
|
+
none: false
|
|
140
|
+
requirements:
|
|
141
|
+
- - ! '>'
|
|
142
|
+
- !ruby/object:Gem::Version
|
|
143
|
+
version: 1.3.1
|
|
144
|
+
requirements: []
|
|
145
|
+
rubyforge_project: ! '[none]'
|
|
146
|
+
rubygems_version: 1.8.24
|
|
147
|
+
signing_key:
|
|
148
|
+
specification_version: 3
|
|
149
|
+
summary: Organise ActiveRecord models into a genealogical tree structure
|
|
150
|
+
test_files: []
|