Class: Og::Entity

Inherits:
Object
  • Object
show all
Includes:
EntityMixin
Defined in:
lib/og/entity.rb

Overview

An Og Managed class. Also contains helper methods.

Class Method Summary collapse

Methods included from EntityMixin

#assign_properties, #delete, #force_save!, included, #insert, #og_clone, #og_quote, #properties_to_hash, #reload, #save, #saved?, #to_rexml, #to_xml, #transaction, #update, #update_by_sql, #update_properties

Class Method Details

.clone(source, *args) ⇒ Object

Clones an object in every possible way (cannot copy HasMany but can copy all others - BelongsTo, etc). Provide a source object as first arguments, the rest (if any) are passed along to the initialize constructor when calling new to make the copied object.



752
753
754
755
756
757
758
759
760
# File 'lib/og/entity.rb', line 752

def clone(source,*args)
  destination = source.class.new(*args)
  copy_properties(source, destination, [], false)
  # Must save here to copy join tables.      
  destination.save!
  copy_relations(source, destination, [])
  destination.save!
  destination
end

.copy_equal_relations(source, destination, ignore = []) ⇒ Object



728
729
730
731
732
733
734
735
# File 'lib/og/entity.rb', line 728

def copy_equal_relations(source, destination, ignore = [])
  source.class.relations.reject{|r| not [Og::JoinsMany, Og::ManyToMany].include?(r.class)}.each do |relation|
    next if relation.name == nil or ignore.include?(relation.name)
    source.send(relation.name).each do |related|
      destination.send(relation.name).send(:<<, related)
    end
  end
end

.copy_inferior_relations(source, destination, ignore = []) ⇒ Object

Copies relations of one record to another. Only copies has_one, refers_to, belongs_to relationships as has_many requires modifying of other objects and cannot be copied (by design). If you think you need to copy these relations, what you need is a joins_many relationship which can be copied.



709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
# File 'lib/og/entity.rb', line 709

def copy_inferior_relations(source, destination, ignore = [])
  real_ignore = Array.new
  
  # Map relation symbols to foreign keys.
  
  ignore.each do |symbol|
     source.class.relations.reject{|r| [Og::JoinsMany, Og::ManyToMany, Og::HasMany].include?(r.class)}.each do |relation|
       if relation.name == symbol.to_s
         real_ignore << relation.foreign_key.to_sym
         break
       end
     end
  end      
  
  # Use instance variable property copier method.
  
  property_copier(source, destination, real_ignore, false, true)
end

.copy_properties(source, destination, ignore = [], use_setter_method = false) ⇒ Object

Accepts source object, destination and ignore. Source and destination are self explanatory; ignore is a list of properties not to copy (i.e. :create_time,:update_time). By default sets the class variables directly on the remote model instance, if you set use_setter_method to true, uses create_time= style copying tactics,



698
699
700
# File 'lib/og/entity.rb', line 698

def copy_properties(source, destination, ignore = [], use_setter_method = false)
  property_copier(source, destination, ignore, use_setter_method, false)
end

.copy_relations(source, destination, ignore = []) ⇒ Object

Copies all relations except HasMany which is impossible to copy. Use a JoinsMany relation instead if you need a copyable HasMany (which is irrational).



741
742
743
744
# File 'lib/og/entity.rb', line 741

def copy_relations(source, destination, ignore = [])
  copy_inferior_relations(source, destination, ignore)
  copy_equal_relations(source, destination, ignore)
end

.entity_from_string(str) ⇒ Object

Converts a string into it’s corresponding class. Added to support STI. Ex: x = “Dave” becomes: (x.class.name == Dave) == true. Returns nil if there’s no such class. – gmosx: investigate this patch! ++



674
675
676
677
678
679
680
681
682
683
# File 'lib/og/entity.rb', line 674

def entity_from_string(str)
  res = nil
  Og::Manager.managed_classes.each do |klass|
    if klass.name == str
      res = klass
      break
    end
  end
  res
end

.property_copier(source, destination, ignore, use_setter_method, relations) ⇒ Object

Does the work of clone_properties and copy_inferior_relations. Syntax is the same with one extra field to tell the routine what it is copying.



766
767
768
769
770
771
772
773
774
775
776
777
778
779
# File 'lib/og/entity.rb', line 766

def property_copier(source,destination,ignore,use_setter_method,relations)
  primary_key_symbol = source.class.primary_key.symbol
  source.class.properties.to_a.each do |symbol, property|
    next if primary_key_symbol == symbol or ignore.include?(symbol) or
     (relations and not property.relation) or (not relations and property.relation)
     
    variable = "@#{symbol}"
    if use_setter_method
      destination.send("#{symbol}=".to_sym,source.instance_variable_get(variable))
    else      
      destination.instance_variable_set(variable, source.instance_variable_get(variable))        
    end
  end
end

.resolve_primary_key(klass) ⇒ Object



647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
# File 'lib/og/entity.rb', line 647

def resolve_primary_key(klass)
  # Is the class annotated with a primary key?

  if pk = klass.ann.self[:primary_key]
    return pk
  end

  # Search the properties, try to find one annotated as primary_key.

  for p in klass.properties.values
    if p.primary_key
      return Property.new(:symbol => p.symbol, :klass => p.klass)
    end
  end

  # The default primary key is oid.

  return Property.new(:symbol => :oid, :klass => Fixnum)
end