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?, #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.



638
639
640
641
642
643
644
645
646
# File 'lib/og/entity.rb', line 638

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



614
615
616
617
618
619
620
621
# File 'lib/og/entity.rb', line 614

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.



595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
# File 'lib/og/entity.rb', line 595

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,



584
585
586
# File 'lib/og/entity.rb', line 584

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).



627
628
629
630
# File 'lib/og/entity.rb', line 627

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! ++



560
561
562
563
564
565
566
567
568
569
# File 'lib/og/entity.rb', line 560

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.



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

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



533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# File 'lib/og/entity.rb', line 533

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