Module: Genealogy::QueryMethods
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/genealogy/query_methods.rb
Overview
Module QueryMethods provides methods to run genealogy queries to retrive relatives by role. It's included by the genealogy enabled AR model
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#ancestors(options = {}) ⇒ ActiveRecord::Relation
get list of known ancestrors iterateing over parents.
- #aunts(options = {}) ⇒ Object
-
#children(options = {}) ⇒ ActiveRecord::Relation
Children.
-
#cousins(options = {}) ⇒ ActiveRecord::Relation
List of uncles and aunts' children.
-
#descendants(options = {}) ⇒ ActiveRecord::Relation
get list of known descendants iterateing over children …
-
#extended_family(options = {}) ⇒ Object
family with option extended: :true.
-
#extended_family_hash(options = {}) ⇒ Object
family_hash with option extended: :true.
-
#family(options = {}) ⇒ Array
family individuals.
-
#family_hash(options = {}) ⇒ Hash
family hash with roles as keys? :spouse and individuals as values.
-
#grandchildren ⇒ ActiveRecord::Relation
List of grandchildren.
-
#grandparents ⇒ 4-elements Array
Paternal_grandfather, paternal_grandmother, maternal_grandfather, maternal_grandmother.
-
#great_grandchildren ⇒ ActiveRecord::Relation
List of grat-grandchildren.
-
#great_grandparents ⇒ 8-elements Array
Paternal_grandfather's father, paternal_grandmother's father, maternal_grandfather's father, maternal_grandmother's father, paternal_grandfather's mother, paternal_grandmother's mother, maternal_grandfather's mother, maternal_grandmother's mother.
-
#half_siblings(options = {}) ⇒ Object
siblings with option half: :only.
- #maternal_aunts(options = {}) ⇒ Object
- #maternal_grandfather ⇒ ActiveRecord, NilClass
- #maternal_grandmother ⇒ ActiveRecord, NilClass
-
#maternal_grandparents ⇒ 2-elements Array
Maternal_grandfather and maternal_grandmother.
-
#maternal_half_siblings(options = {}) ⇒ Object
siblings with option half: :mother.
- #maternal_uncles(options = {}) ⇒ Object
- #nephews(options = {}) ⇒ Object
- #nieces(options = {}) ⇒ Object
-
#nieces_and_nephews(options = {}) ⇒ ActiveRecord::Relation
List of nieces and nephews.
-
#parents ⇒ 2-elements Array
Father and mother.
- #paternal_aunts(options = {}) ⇒ Object
- #paternal_grandfather ⇒ ActiveRecord, NilClass
- #paternal_grandmother ⇒ ActiveRecord, NilClass
-
#paternal_grandparents ⇒ 2-elements Array
Paternal_grandfather and paternal_grandmother.
-
#paternal_half_siblings(options = {}) ⇒ Object
siblings with option half: :father.
- #paternal_uncles(options = {}) ⇒ Object
-
#siblings(options = {}) ⇒ ActiveRecord::Relation
List of fullsiblings and/or halfsiblings.
-
#spouses ⇒ ActiveRecord::Relation
List of individuals with whom has had children.
- #uncles(options = {}) ⇒ Object
-
#uncles_and_aunts(options = {}) ⇒ ActiveRecord::Relation
list of uncles and aunts iterating through parents' siblings.
Instance Method Details
#ancestors(options = {}) ⇒ ActiveRecord::Relation
get list of known ancestrors iterateing over parents
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/genealogy/query_methods.rb', line 131 def ancestors( = {}) ids = [] if [:generations] raise ArgumentError, ":generations option must be an Integer" unless [:generations].is_a? Integer generation_count = 0 generation_ids = parents.compact.map(&:id) while (generation_count < [:generations]) && (generation_ids.length > 0) next_gen_ids = [] ids += generation_ids until generation_ids.empty? ids.unshift(generation_ids.shift) next_gen_ids += gclass.find(ids.first).parents.compact.map(&:id) end generation_ids = next_gen_ids generation_count += 1 end else remaining_ids = parents.compact.map(&:id) until remaining_ids.empty? ids << remaining_ids.shift remaining_ids += gclass.find(ids.last).parents.compact.map(&:id) end end gclass.where(id: ids) end |
#aunts(options = {}) ⇒ Object
222 223 224 |
# File 'lib/genealogy/query_methods.rb', line 222 def aunts( = {}) uncles_and_aunts().females end |
#children(options = {}) ⇒ ActiveRecord::Relation
Returns children.
50 51 52 53 54 55 56 57 58 |
# File 'lib/genealogy/query_methods.rb', line 50 def children( = {}) raise SexError, "Sex value not valid for #{self}. It's needed to look for children" unless gclass.sex_values.include? sex_before_type_cast result = gclass.where("#{gclass::SEX2PARENT[ssex]}_id" => self) if .keys.include? :spouse check_indiv(spouse = [:spouse],opposite_ssex) result = result.where("#{gclass::SEX2PARENT[opposite_ssex]}_id" => spouse ) if spouse end result end |
#cousins(options = {}) ⇒ ActiveRecord::Relation
Returns list of uncles and aunts' children.
250 251 252 253 |
# File 'lib/genealogy/query_methods.rb', line 250 def cousins( = {}) ids = uncles_and_aunts().inject([]){|memo,uncle| memo |= uncle.children.pluck(:id)} gclass.where(id: ids) end |
#descendants(options = {}) ⇒ ActiveRecord::Relation
get list of known descendants iterateing over children …
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/genealogy/query_methods.rb', line 162 def descendants( = {}) ids = [] if [:generations] generation_count = 0 generation_ids = children.map(&:id) while (generation_count < [:generations]) && (generation_ids.length > 0) next_gen_ids = [] ids += generation_ids until generation_ids.empty? ids.unshift(generation_ids.shift) next_gen_ids += gclass.find(ids.first).children.map(&:id) end generation_ids = next_gen_ids generation_count += 1 end else remaining_ids = children.map(&:id) until remaining_ids.empty? ids << remaining_ids.shift remaining_ids += gclass.find(ids.last).children.pluck(:id) # break if (remaining_ids - ids).empty? can be necessary in case of loop. Idem for ancestors method end end gclass.where(id: ids) end |
#extended_family(options = {}) ⇒ Object
family with option extended: :true
355 356 357 |
# File 'lib/genealogy/query_methods.rb', line 355 def extended_family( = {}) family(.merge(extended: true)) end |
#extended_family_hash(options = {}) ⇒ Object
family_hash with option extended: :true
336 337 338 |
# File 'lib/genealogy/query_methods.rb', line 336 def extended_family_hash( = {}) family_hash(.merge(extended: true)) end |
#family(options = {}) ⇒ Array
family individuals
343 344 345 346 347 348 349 350 351 |
# File 'lib/genealogy/query_methods.rb', line 343 def family( = {}) family_hash().inject([]) do |memo, r| [r.last].compact.flatten.each do |relative| relative.role_as_relative = r.first.to_s.singularize.to_sym memo << relative end memo end end |
#family_hash(options = {}) ⇒ Hash
family hash with roles as keys? :spouse and individuals as values. Defaults roles are :father, :mother, :children, :siblings and current_spouse if enabled
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/genealogy/query_methods.rb', line 278 def family_hash( = {}) roles = [:father, :mother, :children, :siblings] roles += [:current_spouse] if self.class.current_spouse_enabled roles += case [:half] when nil [] when :include [:half_siblings] when :include_separately [:paternal_half_siblings, :maternal_half_siblings] when :father [:paternal_half_siblings] when :mother [:maternal_half_siblings] else raise ArgumentError, "Admitted values for :half options are: :father, :mother, :include, :include_separately, nil" end roles += [:paternal_grandfather, :paternal_grandmother, :maternal_grandfather, :maternal_grandmother, :grandchildren, :uncles_and_aunts, :nieces_and_nephews, :cousins] if [:extended] == true res = roles.inject({}){|res,role| res.merge!({role => self.send(role)})} if [:singular_role] == true res2 = { father: res[:father], mother: res[:mother], daughter: res[:children].females, son: res[:children].males, sister: res[:siblings].females, brother: res[:siblings].males } res2[:current_spouse] = res[:current_spouse] if res.has_key? :current_spouse res2.merge!({ paternal_grandfather: res[:paternal_grandfather], paternal_grandmother: res[:paternal_grandmother], maternal_grandfather: res[:maternal_grandfather], maternal_grandmother: res[:maternal_grandmother], grandchild: res[:grandchildren], uncle: res[:uncles_and_aunts].males, aunts: res[:uncles_and_aunts].females, nephew: res[:nieces_and_nephews].males, niece: res[:nieces_and_nephews].females, cousin: res[:cousins] }) if [:extended] == true res2.merge!({ paternal_half_brother: res[:paternal_half_siblings].males, paternal_half_sister: res[:paternal_half_siblings].females, maternal_half_brother: res[:maternal_half_siblings].males, maternal_half_sister: res[:maternal_half_siblings].females, }) if [:half] == :include_separately res = res2 end res end |
#grandchildren ⇒ ActiveRecord::Relation
Returns list of grandchildren.
189 190 191 |
# File 'lib/genealogy/query_methods.rb', line 189 def grandchildren result = children.inject([]){|memo,child| memo |= child.children} end |
#grandparents ⇒ 4-elements Array
Returns paternal_grandfather, paternal_grandmother, maternal_grandfather, maternal_grandmother.
38 39 40 |
# File 'lib/genealogy/query_methods.rb', line 38 def grandparents [paternal_grandfather, paternal_grandmother, maternal_grandfather, maternal_grandmother] end |
#great_grandchildren ⇒ ActiveRecord::Relation
Returns list of grat-grandchildren.
194 195 196 |
# File 'lib/genealogy/query_methods.rb', line 194 def great_grandchildren result = grandchildren.compact.inject([]){|memo,grandchild| memo |= grandchild.children} end |
#great_grandparents ⇒ 8-elements Array
Returns paternal_grandfather's father, paternal_grandmother's father, maternal_grandfather's father, maternal_grandmother's father, paternal_grandfather's mother, paternal_grandmother's mother, maternal_grandfather's mother, maternal_grandmother's mother.
43 44 45 |
# File 'lib/genealogy/query_methods.rb', line 43 def great_grandparents grandparents.inject([]){|memo, gp| memo += (gp.try(:parents) || [nil,nil]) }.flatten end |
#half_siblings(options = {}) ⇒ Object
siblings with option half: :only
111 112 113 |
# File 'lib/genealogy/query_methods.rb', line 111 def half_siblings( = {}) siblings(.merge(half: :only)) end |
#maternal_aunts(options = {}) ⇒ Object
242 243 244 |
# File 'lib/genealogy/query_methods.rb', line 242 def maternal_aunts( = {}) aunts(.merge(lineage: :maternal)) end |
#maternal_grandfather ⇒ ActiveRecord, NilClass
19 20 21 |
# File 'lib/genealogy/query_methods.rb', line 19 def maternal_grandfather mother && mother.father end |
#maternal_grandmother ⇒ ActiveRecord, NilClass
23 24 25 |
# File 'lib/genealogy/query_methods.rb', line 23 def maternal_grandmother mother && mother.mother end |
#maternal_grandparents ⇒ 2-elements Array
Returns maternal_grandfather and maternal_grandmother.
33 34 35 |
# File 'lib/genealogy/query_methods.rb', line 33 def maternal_grandparents (mother && mother.parents) || [nil,nil] end |
#maternal_half_siblings(options = {}) ⇒ Object
siblings with option half: :mother
123 124 125 |
# File 'lib/genealogy/query_methods.rb', line 123 def maternal_half_siblings( = {}) siblings(.merge(half: :mother)) end |
#maternal_uncles(options = {}) ⇒ Object
232 233 234 |
# File 'lib/genealogy/query_methods.rb', line 232 def maternal_uncles( = {}) uncles(.merge(lineage: :maternal)) end |
#nephews(options = {}) ⇒ Object
264 265 266 |
# File 'lib/genealogy/query_methods.rb', line 264 def nephews( = {}) nieces_and_nephews.males end |
#nieces(options = {}) ⇒ Object
269 270 271 |
# File 'lib/genealogy/query_methods.rb', line 269 def nieces( = {}) nieces_and_nephews.females end |
#nieces_and_nephews(options = {}) ⇒ ActiveRecord::Relation
Returns list of nieces and nephews.
258 259 260 261 |
# File 'lib/genealogy/query_methods.rb', line 258 def nieces_and_nephews( = {}) ids = siblings().inject([]){|memo,sib| memo |= sib.children.pluck(:id)} gclass.where(id: ids) end |
#parents ⇒ 2-elements Array
Returns father and mother.
7 8 9 |
# File 'lib/genealogy/query_methods.rb', line 7 def parents [father,mother] end |
#paternal_aunts(options = {}) ⇒ Object
237 238 239 |
# File 'lib/genealogy/query_methods.rb', line 237 def paternal_aunts( = {}) aunts(.merge(lineage: :paternal)) end |
#paternal_grandfather ⇒ ActiveRecord, NilClass
11 12 13 |
# File 'lib/genealogy/query_methods.rb', line 11 def paternal_grandfather father && father.father end |
#paternal_grandmother ⇒ ActiveRecord, NilClass
15 16 17 |
# File 'lib/genealogy/query_methods.rb', line 15 def paternal_grandmother father && father.mother end |
#paternal_grandparents ⇒ 2-elements Array
Returns paternal_grandfather and paternal_grandmother.
28 29 30 |
# File 'lib/genealogy/query_methods.rb', line 28 def paternal_grandparents (father && father.parents) || [nil,nil] end |
#paternal_half_siblings(options = {}) ⇒ Object
siblings with option half: :father
117 118 119 |
# File 'lib/genealogy/query_methods.rb', line 117 def paternal_half_siblings( = {}) siblings(.merge(half: :father)) end |
#paternal_uncles(options = {}) ⇒ Object
227 228 229 |
# File 'lib/genealogy/query_methods.rb', line 227 def paternal_uncles( = {}) uncles(.merge(lineage: :paternal)) end |
#siblings(options = {}) ⇒ ActiveRecord::Relation
Returns list of fullsiblings and/or halfsiblings.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/genealogy/query_methods.rb', line 72 def siblings( = {}) spouse = [:spouse] result = gclass.where.not(id: id) case [:half] when nil # only full siblings result.all_with(:parents).where(father_id: father, mother_id: mother) when :father # common father result = result.all_with(:father).where(father_id: father) if spouse check_indiv(spouse, :female) result.where(mother_id: spouse) elsif mother result.where("mother_id != ? or mother_id is ?", mother_id, nil) else result end when :mother # common mother result = result.all_with(:mother).where(mother_id: mother) if spouse check_indiv(spouse, :male) result.where(father_id: spouse) elsif father result.where("father_id != ? or father_id is ?", father_id, nil) else result end when :only # only half siblings ids = siblings(half: :father).pluck(:id) | siblings(half: :mother).pluck(:id) result.where(id: ids) when :include # including half siblings result.where("father_id = ? or mother_id = ?", father_id, mother_id) else raise ArgumentError, "Admitted values for :half options are: :father, :mother, false, true or nil" end end |
#spouses ⇒ ActiveRecord::Relation
Returns list of individuals with whom has had children.
61 62 63 |
# File 'lib/genealogy/query_methods.rb', line 61 def spouses gclass.where(id: children.pluck("#{gclass::SEX2PARENT[opposite_ssex]}_id".to_sym).compact.uniq) | (self.class.current_spouse_enabled ? [] : [current_spouse]) end |
#uncles(options = {}) ⇒ Object
217 218 219 |
# File 'lib/genealogy/query_methods.rb', line 217 def uncles( = {}) uncles_and_aunts().males end |
#uncles_and_aunts(options = {}) ⇒ ActiveRecord::Relation
list of uncles and aunts iterating through parents' siblings
203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/genealogy/query_methods.rb', line 203 def uncles_and_aunts(={}) relation = case [:lineage] when :paternal [father] when :maternal [mother] else parents end ids = relation.compact.inject([]){|memo,parent| memo |= parent.siblings(half: [:half]).pluck(:id)} gclass.where(id: ids) end |