module Genealogy::AlterMethods

Module AlterMethods provides methods to alter genealogy. It's included by the genealogy enabled AR model

Public Class Methods

generate_method_add_grandparent(lineage,grandparent) click to toggle source

@!macro [attach] generate

@method add_$1_grand$2(grandparent)
Add $1 grand$2
@param [Object] gp grandparent
@raise [Exception] if perform validation is enabled and self is invalid
@return [Boolean]
# File lib/genealogy/alter_methods.rb, line 74
def self.generate_method_add_grandparent(lineage,grandparent)
  relationship = "#{lineage}_grand#{grandparent}"
  define_method "add_#{relationship}" do |gp|
    parent = gclass::LINEAGE2PARENT[lineage]
    raise_if_gap_on(parent)
    check_incompatible_relationship(relationship,gp)
    send(parent).send("add_#{grandparent}",gp)
  end
end
generate_method_add_grandparents_by_lineage(lineage) click to toggle source

@!macro [attach] generate

@method add_$1_grandparents
Add $1 grandparents
@param [Object] gf grandfather
@param [Object] gm grandmother
@raise [Exception] if perform validation is enabled and self is invalid
@return [Boolean]
# File lib/genealogy/alter_methods.rb, line 113
def self.generate_method_add_grandparents_by_lineage(lineage)
  relationship = "#{lineage}_grandparents"
  define_method "add_#{relationship}" do |gf,gm|
    parent = gclass::LINEAGE2PARENT[lineage]
    raise_if_gap_on(parent)
    send(parent).send("add_parents",gf,gm)
  end
end
generate_method_add_parent(parent) click to toggle source

@!macro [attach] generate

@method add_$1(parent)
Add $1
@param [Object] parent
@raise [Exception] if perform validation is enabled and self is invalid
@return [Boolean]
# File lib/genealogy/alter_methods.rb, line 12
def self.generate_method_add_parent(parent)
  define_method "add_#{parent}" do |relative|
    check_incompatible_relationship(parent,relative)
    if gclass.perform_validation_enabled
      self.send("#{parent}=",relative)
      save!
    else
      self.update_attribute(parent,relative)
    end
  end
end
generate_method_remove_grandparent(lineage,grandparent) click to toggle source

@!macro [attach] generate

@method remove_$1_grand$2
remove $1 grand$2
@raise [Exception] if perform validation is enabled and self is invalid
@return [Boolean]
# File lib/genealogy/alter_methods.rb, line 93
def self.generate_method_remove_grandparent(lineage,grandparent)
  relationship = "#{lineage}_grand#{grandparent}"
  define_method "remove_#{relationship}" do
    parent = gclass::LINEAGE2PARENT[lineage]
    raise_if_gap_on(parent)
    send(parent).send("remove_#{grandparent}")
  end
end
generate_method_remove_grandparents_by_lineage(lineage) click to toggle source

@!macro [attach] generate

@method remove_$1_grandparents
remove $1 grandparents
@raise [Exception] if perform validation is enabled and self is invalid
@return [Boolean]
# File lib/genealogy/alter_methods.rb, line 129
def self.generate_method_remove_grandparents_by_lineage(lineage)
  relationship = "#{lineage}_grandparents"
  define_method "remove_#{relationship}" do
    parent = gclass::LINEAGE2PARENT[lineage]
    raise_if_gap_on(parent)
    send(parent).send("remove_parents")
  end
end
generate_method_remove_parent(parent) click to toggle source

@!macro [attach] generate

@method remove_$1
remove $1. Foreign_key set to nil
@raise [Exception] if perform validation is enabled and self is invalid
@return [Boolean]
# File lib/genealogy/alter_methods.rb, line 31
def self.generate_method_remove_parent(parent)
  define_method "remove_#{parent}" do
    if gclass.perform_validation_enabled
      self.send("#{parent}=",nil)
      save!
    else
      self.update_attribute(parent,nil)
    end
  end
end

Public Instance Methods

add_child(child,options={}) click to toggle source

see add_children

# File lib/genealogy/alter_methods.rb, line 311
def add_child(child,options={})
  add_children(child,options)
end
add_children(*args) click to toggle source

add children by assigning self as parent @overload add_children(*children,options={})

@param [Object] children list of children
@param [Hash] options
@option options [Object] spouse if specified, children will have that spouse

@return [Boolean]

# File lib/genealogy/alter_methods.rb, line 290
def add_children(*args)
  options = args.extract_options!
  raise_if_sex_undefined
  check_incompatible_relationship(:children, *args)
  transaction do
    args.inject(true) do |res,child|
      res &= case sex_before_type_cast
      when gclass.sex_male_value
        child.add_mother(options[:spouse]) if options[:spouse]
        child.add_father(self)
      when gclass.sex_female_value
        child.add_father(options[:spouse]) if options[:spouse]
        child.add_mother(self)
      else
        raise SexError, "Sex value not valid for #{self}"
      end
    end
  end
end
add_grandparents(pgf,pgm,mgf,mgm) click to toggle source

add all grandparents calling add_paternal_grandparents and add_maternal_grandparents in a transaction @param [Object] pgf paternal grandfather @param [Object] pgm paternal grandmother @param [Object] mgf maternal grandfather @param [Object] mgm maternal grandmother @see add_paternal_grandparents @see add_maternal_grandparents @return [Boolean]

# File lib/genealogy/alter_methods.rb, line 149
def add_grandparents(pgf,pgm,mgf,mgm)
  transaction do
    add_paternal_grandparents(pgf,pgm)
    add_maternal_grandparents(mgf,mgm)
  end
end
add_maternal_half_sibling(*args)
add_maternal_half_siblings(*args) click to toggle source

@see add_siblings

# File lib/genealogy/alter_methods.rb, line 220
def add_maternal_half_siblings(*args)
  options = args.extract_options!
  options[:half] = :mother
  add_siblings(*args,options)
end
Also aliased as: add_maternal_half_sibling
add_parents(father,mother) click to toggle source

add both parents calling add_father and add_mother in a transaction @param [Object] father @param [Object] mother @see add_father @see add_mother @return [Boolean]

# File lib/genealogy/alter_methods.rb, line 50
def add_parents(father,mother)
  transaction do
    add_father(father)
    add_mother(mother)
  end
end
add_paternal_half_sibling(*args)
add_paternal_half_siblings(*args) click to toggle source

@see add_siblings

# File lib/genealogy/alter_methods.rb, line 213
def add_paternal_half_siblings(*args)
  options = args.extract_options!
  options[:half] = :father
  add_siblings(*args,options)
end
Also aliased as: add_paternal_half_sibling
add_sibling(sibling,options={}) click to toggle source

@see add_siblings

# File lib/genealogy/alter_methods.rb, line 208
def add_sibling(sibling,options={})
  add_siblings(sibling,options)
end
add_siblings(*args) click to toggle source

add siblings by assigning same parents to individuals passed as arguments @overload add_siblings(*siblings,options={})

@param [Object] siblings list of siblings
@param [Hash] options
@option options [Symbol] half :father for paternal half siblings and :mother for maternal half siblings
@option options [Object] spouse if specified, passed individual will be used as mother in case of half sibling

@return [Boolean]

# File lib/genealogy/alter_methods.rb, line 174
def add_siblings(*args)
  options = args.extract_options!
  case options[:half]
  when :father
    check_incompatible_relationship(:paternal_half_sibling, *args)
  when :mother
    check_incompatible_relationship(:maternal_half_sibling, *args)
  when nil
    check_incompatible_relationship(:sibling, *args)
  end

  transaction do
    args.inject(true) do |res,sib|
      res &= case options[:half]
      when :father
        raise LineageGapException, "Can't add paternal halfsiblings without a father" unless father
        sib.add_mother(options[:spouse]) if options[:spouse]
        sib.add_father(father)
      when :mother
        raise LineageGapException, "Can't add maternal halfsiblings without a mother" unless mother
        sib.add_father(options[:spouse]) if options[:spouse]
        sib.add_mother(mother)
      when nil
        raise LineageGapException, "Can't add siblings without parents" unless father and mother
        sib.add_father(father)
        sib.add_mother(mother)
      else
        raise ArgumentError, "Admitted values for :half options are: :father, :mother or nil"
      end
    end
  end
end
remove_child(child,options={}) click to toggle source

see remove_children

# File lib/genealogy/alter_methods.rb, line 352
def remove_child(child,options={})
  remove_children(child,options)
end
remove_children(*args) click to toggle source

remove children by nullifying the parent corresponding to self @overload remove_children(*children,options={})

@param [Object] children list of children
@param [Hash] options
@option options [Boolean] remove_other_parent if specified, passed individuals' mother will also be nullified

@return [Boolean] true if at least one child was affected, false otherwise

# File lib/genealogy/alter_methods.rb, line 321
def remove_children(*args)
  options = args.extract_options!

  raise_if_sex_undefined

  resulting_indivs = if args.blank?
    children(options)
  else
    args & children(options)
  end

  transaction do
    resulting_indivs.each do |child|
      if options[:remove_other_parent] == true
        child.remove_parents
      else
        case sex_before_type_cast
        when gclass.sex_male_value
          child.remove_father
        when gclass.sex_female_value
          child.remove_mother
        else
          raise SexError, "Sex value not valid for #{self}"
        end
      end
    end
  end
  !resulting_indivs.empty? #returned value must be true if self has at least a siblings to affect
end
remove_grandparents() click to toggle source

remove all grandparents calling remove_paternal_grandparents and remove_maternal_grandparents in a transaction @see remove_paternal_grandparents @see remove_maternal_grandparents @return [Boolean]

# File lib/genealogy/alter_methods.rb, line 160
def remove_grandparents
   transaction do
     remove_paternal_grandparents
     remove_maternal_grandparents
   end
 end
remove_maternal_half_sibling(*args)
remove_maternal_half_siblings(*args) click to toggle source

@see remove_siblings

# File lib/genealogy/alter_methods.rb, line 274
def remove_maternal_half_siblings(*args)
  options = args.extract_options!
  options[:half] = :mother
  remove_siblings(*args,options)
end
Also aliased as: remove_maternal_half_sibling
remove_parents() click to toggle source

remove both parents calling remove_father and remove_mother in a transaction @see remove_father @see remove_mother @return [Boolean]

# File lib/genealogy/alter_methods.rb, line 61
def remove_parents
  transaction do
    remove_father
    remove_mother
  end
end
remove_paternal_half_sibling(*args)
remove_paternal_half_siblings(*args) click to toggle source

@see remove_siblings

# File lib/genealogy/alter_methods.rb, line 267
def remove_paternal_half_siblings(*args)
  options = args.extract_options!
  options[:half] = :father
  remove_siblings(*args,options)
end
Also aliased as: remove_paternal_half_sibling
remove_sibling(sib,options={}) click to toggle source

@see remove_siblings

# File lib/genealogy/alter_methods.rb, line 262
def remove_sibling(sib,options={})
  remove_siblings(sib,options)
end
remove_siblings(*args) click to toggle source

remove siblings by nullifying parents of passed individuals @overload remove_siblings(*siblings,options={})

@param [Object] siblings list of siblings
@param [Hash] options
@option options [Symbol] half :father for paternal half siblings and :mother for maternal half siblings
@option options [Boolean] remove_other_parent if specified, passed individuals' mother will also be nullified

@return [Boolean] true if at least one sibling was affected, false otherwise

# File lib/genealogy/alter_methods.rb, line 236
def remove_siblings(*args)
  options = args.extract_options!
  raise ArgumentError.new("Unknown option value: half: #{options[:half]}.") if (options[:half] and ![:father,:mother].include?(options[:half]))
  resulting_indivs = if args.blank?
    siblings(options)
  else
    args & siblings(options)
  end
  transaction do
    resulting_indivs.each do |sib|
      case options[:half]
      when :father
        sib.remove_father
        sib.remove_mother if options[:remove_other_parent] == true
      when :mother
        sib.remove_father if options[:remove_other_parent] == true
        sib.remove_mother
      when nil
        sib.remove_parents
      end
    end
  end
  !resulting_indivs.empty? #returned value must be true if self has at least a siblings to affect
end

Private Instance Methods

raise_if_gap_on(relative) click to toggle source
# File lib/genealogy/alter_methods.rb, line 358
def raise_if_gap_on(relative)
  raise LineageGapException, "#{self} doesn't have #{relative}" unless send(relative)
end
raise_if_sex_undefined() click to toggle source
# File lib/genealogy/alter_methods.rb, line 362
def raise_if_sex_undefined
  raise SexError, "Can't proceed if sex undefined for #{self}" unless is_male? or is_female?
end