genealogy 0.3.0 → 0.3.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/genealogy/alter_methods.rb +77 -13
- data/lib/genealogy/constants.rb +22 -1
- data/lib/genealogy/genealogy.rb +10 -7
- data/lib/genealogy/query_methods.rb +146 -17
- data/lib/genealogy/spouse_methods.rb +15 -10
- data/lib/genealogy/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzJjYzM4NzU0NWU4OWI3N2I1OWUzZWU5OGI3M2VlOTc3NTU5MGU1Yg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZWRhODI1YjMxMjA1NDA3MTQ3ZGNhN2NhNDgyOTEyMDQ2ZGY5MmIyZA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZmNiN2MwOTJkN2E2NmExNmMyY2MzYWI5ZWJkMTkwNjE2YTJkNzJlMzM4MDll
|
10
|
+
MTE3MTM0YmI1NWM0N2U3YzA0NDAxYzg1ZDMxNTllMzZkYzJmMTMzMTc1NTc3
|
11
|
+
MTgyNTMyM2FkZTlkMGY1MGFhZDllM2Q2OWU0MzNlNTc1ZjJhMDQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MmY0Yzc1M2FjY2ZjYjJhZWFlZTcyMDMwYmFjOWIxNmQwYzAyMjAxM2E1N2Nl
|
14
|
+
ZTFiYjQzYzBmMzRlNzBkMmI4NWQxY2JkMDg2OGYzZjg4MTdmOWY4ZDBkZTRm
|
15
|
+
N2QyNDM5OWY2Y2RhYWNlNjdkZjBjNTljNWEyMDJhMjdkMzExNzU=
|
@@ -8,7 +8,7 @@ module Genealogy
|
|
8
8
|
# add method
|
9
9
|
define_method "add_#{parent}" do |relative|
|
10
10
|
unless relative.nil?
|
11
|
-
raise IncompatibleObjectException, "
|
11
|
+
raise IncompatibleObjectException, "Both linked objects must be instances of class with genealogy enabled. Got classes #{relative.class} and #{self.genealogy_class}" unless relative.class.respond_to?(:genealogy_enabled)
|
12
12
|
incompatible_parents = self.offspring | self.siblings.to_a | [self]
|
13
13
|
raise IncompatibleRelationshipException, "#{relative} can't be #{parent} of #{self}" if incompatible_parents.include? relative
|
14
14
|
raise WrongSexException, "Can't add a #{relative.sex} #{parent}" unless (parent == :father and relative.is_male?) or (parent == :mother and relative.is_female?)
|
@@ -45,13 +45,13 @@ module Genealogy
|
|
45
45
|
[:father, :mother].each do |parent|
|
46
46
|
[:father, :mother].each do |grandparent|
|
47
47
|
# add one
|
48
|
-
define_method "add_#{Genealogy::
|
48
|
+
define_method "add_#{Genealogy::PARENT2LINEAGE[parent]}_grand#{grandparent}" do |relative|
|
49
49
|
raise IncompatibleRelationshipException, "#{self} can't be grand#{grandparent} of itself" if relative == self
|
50
50
|
raise_if_gap_on(parent)
|
51
51
|
send(parent).send("add_#{grandparent}",relative)
|
52
52
|
end
|
53
53
|
# remove one
|
54
|
-
define_method "remove_#{Genealogy::
|
54
|
+
define_method "remove_#{Genealogy::PARENT2LINEAGE[parent]}_grand#{grandparent}" do
|
55
55
|
raise_if_gap_on(parent)
|
56
56
|
send(parent).send("remove_#{grandparent}")
|
57
57
|
end
|
@@ -60,12 +60,12 @@ module Genealogy
|
|
60
60
|
|
61
61
|
[:father, :mother].each do |parent|
|
62
62
|
# add two by lineage
|
63
|
-
define_method "add_#{Genealogy::
|
63
|
+
define_method "add_#{Genealogy::PARENT2LINEAGE[parent]}_grandparents" do |grandfather,grandmother|
|
64
64
|
raise_if_gap_on(parent)
|
65
65
|
send(parent).send("add_parents",grandfather,grandmother)
|
66
66
|
end
|
67
67
|
# remove two by lineage
|
68
|
-
define_method "remove_#{Genealogy::
|
68
|
+
define_method "remove_#{Genealogy::PARENT2LINEAGE[parent]}_grandparents" do
|
69
69
|
raise_if_gap_on(parent)
|
70
70
|
send(parent).send("remove_parents")
|
71
71
|
end
|
@@ -91,18 +91,20 @@ module Genealogy
|
|
91
91
|
## siblings
|
92
92
|
def add_siblings(*args)
|
93
93
|
options = args.extract_options!
|
94
|
-
raise LineageGapException, "Can't add siblings if both parents are nil" unless father and mother
|
95
94
|
raise IncompatibleRelationshipException, "Can't add an ancestor as sibling" unless (ancestors.to_a & args).empty?
|
96
95
|
transaction do
|
97
96
|
args.each do |sib|
|
98
97
|
case options[:half]
|
99
98
|
when :father
|
99
|
+
raise LineageGapException, "Can't add paternal halfsiblings without a father" unless father
|
100
100
|
sib.add_father(self.father)
|
101
101
|
sib.add_mother(options[:spouse]) if options[:spouse]
|
102
102
|
when :mother
|
103
|
+
raise LineageGapException, "Can't add maternal halfsiblings without a mother" unless mother
|
103
104
|
sib.add_father(options[:spouse]) if options[:spouse]
|
104
105
|
sib.add_mother(self.mother)
|
105
106
|
when nil
|
107
|
+
raise LineageGapException, "Can't add siblings without parents" unless father and mother
|
106
108
|
sib.add_father(self.father)
|
107
109
|
sib.add_mother(self.mother)
|
108
110
|
else
|
@@ -112,10 +114,20 @@ module Genealogy
|
|
112
114
|
end
|
113
115
|
end
|
114
116
|
|
115
|
-
def
|
116
|
-
options
|
117
|
+
def add_sibling(sib,options={})
|
118
|
+
add_siblings(sib,options)
|
119
|
+
end
|
120
|
+
|
121
|
+
def remove_siblings(*args)
|
122
|
+
options = args.extract_options!
|
123
|
+
|
124
|
+
raise WrongOptionException.new("Unknown option value: :half => #{options[:half]}.") if (options[:half] and ![:father,:mother].include?(options[:half]))
|
117
125
|
|
118
|
-
resulting_indivs =
|
126
|
+
resulting_indivs = if args.blank?
|
127
|
+
siblings(options)
|
128
|
+
else
|
129
|
+
args & siblings(options)
|
130
|
+
end
|
119
131
|
|
120
132
|
transaction do
|
121
133
|
|
@@ -130,12 +142,50 @@ module Genealogy
|
|
130
142
|
when nil
|
131
143
|
sib.remove_parents
|
132
144
|
end
|
133
|
-
|
134
145
|
end
|
146
|
+
|
135
147
|
end
|
136
148
|
|
149
|
+
!resulting_indivs.empty? #returned value must be true if self has at least a siblings to affect
|
150
|
+
|
137
151
|
end
|
138
152
|
|
153
|
+
def remove_sibling(sib,options={})
|
154
|
+
remove_siblings(sib,options)
|
155
|
+
end
|
156
|
+
|
157
|
+
[:father, :mother].each do |parent|
|
158
|
+
|
159
|
+
# add paternal/maternal half_siblings
|
160
|
+
define_method "add_#{Genealogy::PARENT2LINEAGE[parent]}_half_siblings" do | *args |
|
161
|
+
options = args.extract_options!
|
162
|
+
options[:half] = parent
|
163
|
+
args << options
|
164
|
+
send("add_siblings",*args)
|
165
|
+
end
|
166
|
+
|
167
|
+
# add paternal/maternal half_sibling
|
168
|
+
define_method "add_#{Genealogy::PARENT2LINEAGE[parent]}_half_sibling" do | sib,options={} |
|
169
|
+
options[:half] = parent
|
170
|
+
send("add_sibling",sib,options)
|
171
|
+
end
|
172
|
+
|
173
|
+
# remove paternal/maternal half_siblings
|
174
|
+
define_method "remove_#{Genealogy::PARENT2LINEAGE[parent]}_half_siblings" do | *args |
|
175
|
+
options = args.extract_options!
|
176
|
+
options[:half] = parent
|
177
|
+
args << options
|
178
|
+
send("remove_siblings",*args)
|
179
|
+
end
|
180
|
+
|
181
|
+
# remove paternal/maternal half_sibling
|
182
|
+
define_method "remove_#{Genealogy::PARENT2LINEAGE[parent]}_half_sibling" do | sib,options={} |
|
183
|
+
options[:half] = parent
|
184
|
+
send("remove_sibling",sib,options)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
|
139
189
|
# offspring
|
140
190
|
def add_offspring(*args)
|
141
191
|
options = args.extract_options!
|
@@ -156,11 +206,21 @@ module Genealogy
|
|
156
206
|
end
|
157
207
|
end
|
158
208
|
|
159
|
-
def
|
209
|
+
def add_child(child,options={})
|
210
|
+
add_offspring(child,options)
|
211
|
+
end
|
212
|
+
|
213
|
+
def remove_offspring(*args)
|
214
|
+
options = args.extract_options!
|
160
215
|
|
161
216
|
raise_if_sex_undefined
|
162
217
|
|
163
|
-
resulting_indivs =
|
218
|
+
resulting_indivs = if args.blank?
|
219
|
+
offspring(options)
|
220
|
+
else
|
221
|
+
args & offspring(options)
|
222
|
+
end
|
223
|
+
|
164
224
|
transaction do
|
165
225
|
resulting_indivs.each do |child|
|
166
226
|
if options[:affect_spouse] == true
|
@@ -175,7 +235,11 @@ module Genealogy
|
|
175
235
|
end
|
176
236
|
end
|
177
237
|
end
|
178
|
-
resulting_indivs.empty?
|
238
|
+
!resulting_indivs.empty? #returned value must be true if self has at least a siblings to affect
|
239
|
+
end
|
240
|
+
|
241
|
+
def remove_child(child,options={})
|
242
|
+
remove_offspring(child,options)
|
179
243
|
end
|
180
244
|
|
181
245
|
private
|
data/lib/genealogy/constants.rb
CHANGED
@@ -1,3 +1,24 @@
|
|
1
1
|
module Genealogy
|
2
|
-
|
2
|
+
PARENT2LINEAGE = { :father => :paternal, :mother => :maternal }
|
3
|
+
LINEAGE2PARENT = PARENT2LINEAGE.invert
|
4
|
+
PARENT2SEX = { :father => :male, :mother => :female }
|
5
|
+
SEX2PARENT = PARENT2SEX.invert
|
6
|
+
OPPOSITESEX = {:male => :female, :female => :male}
|
7
|
+
|
8
|
+
AKA = {
|
9
|
+
:father => "F",
|
10
|
+
:mother => "M",
|
11
|
+
:paternal_grandfather => "PGF",
|
12
|
+
:paternal_grandmother => "PGM",
|
13
|
+
:maternal_grandfather => "MGF",
|
14
|
+
:maternal_grandmother => "MGM",
|
15
|
+
:children => "C",
|
16
|
+
:siblings => "S",
|
17
|
+
:half_siblings => "HS",
|
18
|
+
:paternal_half_siblings => "PHS",
|
19
|
+
:maternal_half_siblings => "MHS",
|
20
|
+
:grandchildren => "GC",
|
21
|
+
:uncles_and_aunts => "U&A",
|
22
|
+
:nieces_and_nephews => "N&N"
|
23
|
+
}
|
3
24
|
end
|
data/lib/genealogy/genealogy.rb
CHANGED
@@ -19,17 +19,20 @@ module Genealogy
|
|
19
19
|
|
20
20
|
def has_parents options = {}
|
21
21
|
|
22
|
-
admitted_keys = [:sex_column, :sex_values, :father_column, :mother_column, :
|
22
|
+
admitted_keys = [:sex_column, :sex_values, :father_column, :mother_column, :current_spouse_column, :current_spouse]
|
23
23
|
check_options(options, admitted_keys) do |key, value|
|
24
24
|
if key == :sex_values
|
25
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
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
class_attribute :
|
30
|
-
self.
|
31
|
-
|
32
|
-
|
29
|
+
class_attribute :genealogy_enabled, :current_spouse_enabled, :genealogy_class
|
30
|
+
self.genealogy_enabled = true
|
31
|
+
self.current_spouse_enabled = options[:current_spouse].try(:==,true) || false
|
32
|
+
self.genealogy_class = self #keep track of the original extend class to prevent wrong scopes in query method in case of STI
|
33
|
+
|
34
|
+
tracked_relatives = [:father, :mother]
|
35
|
+
tracked_relatives << :current_spouse if current_spouse_enabled
|
33
36
|
|
34
37
|
## sex
|
35
38
|
# class attributes
|
@@ -45,7 +48,7 @@ module Genealogy
|
|
45
48
|
validates_format_of sex_column, :with => /[#{sex_values.join}]/
|
46
49
|
|
47
50
|
## relatives associations
|
48
|
-
|
51
|
+
tracked_relatives.each do |key|
|
49
52
|
# class attribute where is stored the correspondig foreign_key column name
|
50
53
|
class_attribute_name = "#{key}_column"
|
51
54
|
foreign_key = "#{key}_id"
|
@@ -61,7 +64,7 @@ module Genealogy
|
|
61
64
|
# Include instance methods and class methods
|
62
65
|
include Genealogy::QueryMethods
|
63
66
|
include Genealogy::AlterMethods
|
64
|
-
include Genealogy::SpouseMethods if
|
67
|
+
include Genealogy::SpouseMethods if current_spouse_enabled
|
65
68
|
|
66
69
|
end
|
67
70
|
|
@@ -4,10 +4,17 @@ module Genealogy
|
|
4
4
|
|
5
5
|
# parents
|
6
6
|
def parents
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
[father,mother]
|
8
|
+
end
|
9
|
+
|
10
|
+
# eligible
|
11
|
+
[:father, :mother].each do |parent|
|
12
|
+
define_method "eligible_#{parent}s" do
|
13
|
+
if send(parent)
|
14
|
+
[]
|
15
|
+
else
|
16
|
+
self.genealogy_class.send("#{Genealogy::PARENT2SEX[parent]}s") - descendants - [self]
|
17
|
+
end
|
11
18
|
end
|
12
19
|
end
|
13
20
|
|
@@ -16,52 +23,89 @@ module Genealogy
|
|
16
23
|
[:father, :mother].each do |grandparent|
|
17
24
|
|
18
25
|
# get one
|
19
|
-
define_method "#{Genealogy::
|
26
|
+
define_method "#{Genealogy::PARENT2LINEAGE[parent]}_grand#{grandparent}" do
|
20
27
|
send(parent) && send(parent).send(grandparent)
|
21
28
|
end
|
22
29
|
|
30
|
+
# eligible
|
31
|
+
define_method "eligible_#{Genealogy::PARENT2LINEAGE[parent]}_grand#{grandparent}s" do
|
32
|
+
if send(parent) and send("#{Genealogy::PARENT2LINEAGE[parent]}_grand#{grandparent}").nil?
|
33
|
+
send(parent).send("eligible_#{grandparent}s") - [self]
|
34
|
+
else
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
23
39
|
end
|
24
40
|
|
25
41
|
# get two by lineage
|
26
|
-
define_method "#{Genealogy::
|
27
|
-
(send(parent) && send(parent).parents) || []
|
42
|
+
define_method "#{Genealogy::PARENT2LINEAGE[parent]}_grandparents" do
|
43
|
+
(send(parent) && send(parent).parents) || [nil,nil]
|
28
44
|
end
|
29
45
|
|
30
46
|
end
|
31
47
|
|
32
|
-
# get all
|
33
48
|
def grandparents
|
34
49
|
result = []
|
35
50
|
[:father, :mother].each do |parent|
|
36
51
|
[:father, :mother].each do |grandparent|
|
37
|
-
result << send("#{Genealogy::
|
52
|
+
result << send("#{Genealogy::PARENT2LINEAGE[parent]}_grand#{grandparent}")
|
38
53
|
end
|
39
54
|
end
|
40
|
-
result.compact! if result.all?{|gp| gp.nil? }
|
55
|
+
# result.compact! if result.all?{|gp| gp.nil? }
|
41
56
|
result
|
42
57
|
end
|
43
58
|
|
59
|
+
# offspring
|
44
60
|
def offspring(options = {})
|
45
|
-
|
46
61
|
if spouse = options[:spouse]
|
47
62
|
raise WrongSexException, "Something wrong with spouse #{spouse} gender." if spouse.sex == sex
|
48
63
|
end
|
49
64
|
case sex
|
50
65
|
when sex_male_value
|
51
|
-
|
66
|
+
if options.keys.include?(:spouse)
|
67
|
+
self.genealogy_class.find_all_by_father_id_and_mother_id(id,spouse.try(:id))
|
68
|
+
else
|
69
|
+
self.genealogy_class.find_all_by_father_id(id)
|
70
|
+
end
|
52
71
|
when sex_female_value
|
53
|
-
|
72
|
+
if options.keys.include?(:spouse)
|
73
|
+
self.genealogy_class.find_all_by_mother_id_and_father_id(id,spouse.try(:id))
|
74
|
+
else
|
75
|
+
self.genealogy_class.find_all_by_mother_id(id)
|
76
|
+
end
|
54
77
|
end
|
55
78
|
end
|
79
|
+
alias_method :children, :offspring
|
80
|
+
|
81
|
+
def eligible_offspring
|
82
|
+
self.genealogy_class.all - ancestors - offspring - siblings - [self]
|
83
|
+
end
|
84
|
+
alias_method :eligible_children, :eligible_offspring
|
85
|
+
|
86
|
+
# spouses
|
87
|
+
def spouses
|
88
|
+
parent_method = Genealogy::SEX2PARENT[Genealogy::OPPOSITESEX[sex_to_s.to_sym]]
|
89
|
+
offspring.collect{|child| child.send(parent_method)}.uniq
|
90
|
+
end
|
56
91
|
|
92
|
+
def eligible_spouses
|
93
|
+
self.genealogy_class.send("#{Genealogy::OPPOSITESEX[sex_to_s.to_sym]}s") - spouses
|
94
|
+
end
|
95
|
+
|
96
|
+
# siblings
|
57
97
|
def siblings(options = {})
|
58
98
|
result = case options[:half]
|
59
|
-
when nil #
|
60
|
-
|
99
|
+
when nil # only full siblings
|
100
|
+
unless parents.include?(nil)
|
101
|
+
father.try(:offspring, :spouse => mother ).to_a
|
102
|
+
else
|
103
|
+
[]
|
104
|
+
end
|
61
105
|
when :father # common father
|
62
|
-
father.try(:offspring, :spouse => options[:spouse]).to_a - mother.try(:offspring).to_a
|
106
|
+
father.try(:offspring, options.keys.include?(:spouse) ? {:spouse => options[:spouse]} : {}).to_a - mother.try(:offspring).to_a
|
63
107
|
when :mother # common mother
|
64
|
-
mother.try(:offspring, :spouse => options[:spouse]).to_a - father.try(:offspring).to_a
|
108
|
+
mother.try(:offspring, options.keys.include?(:spouse) ? {:spouse => options[:spouse]} : {}).to_a - father.try(:offspring).to_a
|
65
109
|
when :only # only half siblings
|
66
110
|
siblings(:half => :include) - siblings
|
67
111
|
when :include # including half siblings
|
@@ -72,6 +116,10 @@ module Genealogy
|
|
72
116
|
result.uniq - [self]
|
73
117
|
end
|
74
118
|
|
119
|
+
def eligible_siblings
|
120
|
+
self.genealogy_class.all - ancestors - siblings(:half => :include) - [self]
|
121
|
+
end
|
122
|
+
|
75
123
|
def half_siblings
|
76
124
|
siblings(:half => :only)
|
77
125
|
# todo: inprove with option :father and :mother
|
@@ -85,6 +133,11 @@ module Genealogy
|
|
85
133
|
siblings(:half => :mother)
|
86
134
|
end
|
87
135
|
|
136
|
+
alias_method :eligible_half_siblings, :eligible_siblings
|
137
|
+
alias_method :eligible_paternal_half_siblings, :eligible_siblings
|
138
|
+
alias_method :eligible_maternal_half_siblings, :eligible_siblings
|
139
|
+
|
140
|
+
# ancestors
|
88
141
|
def ancestors
|
89
142
|
result = []
|
90
143
|
remaining = parents.to_a.compact
|
@@ -95,16 +148,86 @@ module Genealogy
|
|
95
148
|
result.uniq
|
96
149
|
end
|
97
150
|
|
151
|
+
# descendants
|
98
152
|
def descendants
|
99
153
|
result = []
|
100
154
|
remaining = offspring.to_a.compact
|
101
155
|
until remaining.empty?
|
102
156
|
result << remaining.shift
|
103
157
|
remaining += result.last.offspring.to_a.compact
|
158
|
+
# break if (remaining - result).empty? can be necessary in case of loop. Idem for ancestors method
|
104
159
|
end
|
105
160
|
result.uniq
|
106
161
|
end
|
107
162
|
|
163
|
+
def grandchildren
|
164
|
+
offspring.inject([]){|memo,child| memo |= child.offspring}
|
165
|
+
end
|
166
|
+
|
167
|
+
def uncles_and_aunts
|
168
|
+
parents.compact.inject([]){|memo,parent| memo |= parent.siblings}
|
169
|
+
end
|
170
|
+
|
171
|
+
def nieces_and_nephews
|
172
|
+
siblings.inject([]){|memo,sib| memo |= sib.offspring}
|
173
|
+
end
|
174
|
+
|
175
|
+
def family(options = {})
|
176
|
+
res = [self] | siblings | parents | offspring
|
177
|
+
res |= case options[:half]
|
178
|
+
when nil
|
179
|
+
[]
|
180
|
+
when :include
|
181
|
+
half_siblings
|
182
|
+
when :father
|
183
|
+
paternal_half_siblings
|
184
|
+
when :mother
|
185
|
+
maternal_half_siblings
|
186
|
+
else
|
187
|
+
raise WrongOptionValueException, "Admitted values for :half options are: :father, :mother, :include, nil"
|
188
|
+
end
|
189
|
+
offspring.inject(res){|memo,child| memo |= child.parents}.compact
|
190
|
+
end
|
191
|
+
|
192
|
+
def family_hash(options = {})
|
193
|
+
roles = [:father, :mother, :children, :siblings]
|
194
|
+
roles += case options[:half]
|
195
|
+
when nil
|
196
|
+
[]
|
197
|
+
when :include
|
198
|
+
[:half_siblings]
|
199
|
+
when :father
|
200
|
+
[:paternal_half_siblings]
|
201
|
+
when :mother
|
202
|
+
[:maternal_half_siblings]
|
203
|
+
else
|
204
|
+
raise WrongOptionValueException, "Admitted values for :half options are: :father, :mother, :include, nil"
|
205
|
+
end
|
206
|
+
h = {}
|
207
|
+
roles.each{|role| h[role] = self.send(role)}
|
208
|
+
h
|
209
|
+
end
|
210
|
+
|
211
|
+
def extended_family(options = {})
|
212
|
+
(family(options) + grandparents + grandchildren + uncles_and_aunts + nieces_and_nephews).compact
|
213
|
+
end
|
214
|
+
|
215
|
+
def extended_family_hash(options = {})
|
216
|
+
h = family_hash(options)
|
217
|
+
[:paternal_grandfather, :paternal_grandmother, :maternal_grandfather, :maternal_grandmother, :grandchildren, :uncles_and_aunts, :nieces_and_nephews].each{|role| h[role] = self.send(role)}
|
218
|
+
h
|
219
|
+
end
|
220
|
+
|
221
|
+
def sex_to_s
|
222
|
+
case sex
|
223
|
+
when sex_male_value
|
224
|
+
'male'
|
225
|
+
when sex_female_value
|
226
|
+
'female'
|
227
|
+
else
|
228
|
+
raise "undefined sex for #{self}"
|
229
|
+
end
|
230
|
+
end
|
108
231
|
|
109
232
|
def is_female?
|
110
233
|
sex == sex_female_value
|
@@ -115,6 +238,12 @@ module Genealogy
|
|
115
238
|
end
|
116
239
|
|
117
240
|
module ClassMethods
|
241
|
+
def males
|
242
|
+
where(sex_column => sex_male_value)
|
243
|
+
end
|
244
|
+
def females
|
245
|
+
where(sex_column => sex_female_value)
|
246
|
+
end
|
118
247
|
end
|
119
248
|
|
120
249
|
end
|
@@ -3,11 +3,11 @@ module Genealogy
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
# add method
|
6
|
-
def
|
7
|
-
raise IncompatibleObjectException, "Linked objects must be instances of the same class" unless obj.is_a? self.
|
8
|
-
raise WrongSexException, "Can't add
|
9
|
-
self.
|
10
|
-
obj.
|
6
|
+
def add_current_spouse(obj)
|
7
|
+
raise IncompatibleObjectException, "Linked objects must be instances of the same class" unless obj.is_a? self.genealogy_class
|
8
|
+
raise WrongSexException, "Can't add current_spouse with same sex" if self.sex == obj.sex
|
9
|
+
self.current_spouse = obj
|
10
|
+
obj.current_spouse = self
|
11
11
|
transaction do
|
12
12
|
obj.save!
|
13
13
|
save!
|
@@ -15,16 +15,21 @@ module Genealogy
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# remove method
|
18
|
-
def
|
18
|
+
def remove_current_spouse
|
19
19
|
transaction do
|
20
|
-
|
21
|
-
|
22
|
-
self.
|
23
|
-
|
20
|
+
ex_current_spouse = current_spouse
|
21
|
+
current_spouse.current_spouse = nil
|
22
|
+
self.current_spouse = nil
|
23
|
+
ex_current_spouse.save!
|
24
24
|
save!
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
# query methods
|
29
|
+
def eligible_current_spouses
|
30
|
+
self.genealogy_class.send("#{Genealogy::OPPOSITESEX[sex_to_s.to_sym]}s") - spouses
|
31
|
+
end
|
32
|
+
|
28
33
|
module ClassMethods
|
29
34
|
end
|
30
35
|
|
data/lib/genealogy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: genealogy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- masciugo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ! '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: gem-release
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
description: Genealogy is a ruby gem library which extend ActiveRecord::Base class
|
98
112
|
with familiar relationships capabilities in order to build and query genealogies
|
99
113
|
email:
|
@@ -110,7 +124,7 @@ files:
|
|
110
124
|
- lib/genealogy/query_methods.rb
|
111
125
|
- lib/genealogy/spouse_methods.rb
|
112
126
|
- lib/genealogy/version.rb
|
113
|
-
homepage: https://github.com
|
127
|
+
homepage: https://github.com/masciugo/genealogy
|
114
128
|
licenses:
|
115
129
|
- MIT
|
116
130
|
metadata: {}
|