lib/og/relation.rb in og-0.24.0 vs lib/og/relation.rb in og-0.25.0

- old
+ new

@@ -4,64 +4,64 @@ require 'mega/inheritor' require 'mega/annotation' module Og -# A relation between Entities. +# A relation between Entities. #-- # Relations are resolved in multiple passes. First # the relations are logged in :relations... #++ class Relation # The parameters of this relation. - + attr_accessor :options - + # A generalized initialize method for all relations. # Contains common setup code. - + def initialize(args, options = {}) @options = options @options.update(args.pop) if args.last.is_a?(Hash) target_name = if collection :target_plural_name - else - :target_singular_name + else + :target_singular_name end # Check that all needed options are provided. - + if args.empty? or (not (args.last.is_a?(Class) or args.last.is_a?(Symbol))) raise 'Class of target not defined' end # Try to set the target class. Checks for class and # class symbol. - + if args.last.to_s.capitalized? @options[:target_class] = args.pop end - + # Try to set the target name. - + if args.last.is_a? Symbol @options[target_name] = args.pop - end - + end + # Inflect target_class if not provided. - + @options[:target_class] ||= @options[target_name].to_s.singular.camelize.intern - + # FIXME: this is a hack! # setup() rescue nil end # Get an option. - + def [](key) @options[key] end # Set an option. @@ -69,30 +69,30 @@ def []=(key, val) @options[key] = val end # Is this a polymorphic marker? - + def polymorphic_marker? - target_class == Object + target_class == Object end - + # Is this a polymorphic relation ? - + def polymorphic? - target_class.ann.this[:polymorphic] + target_class.ann.self[:polymorphic] end - + # Resolve a polymorphic target class. # Overrided in subclasses. - + def resolve_polymorphic end - + # This method is implemented in subclasses. - - def enchant + + def enchant end # Access the hash values as methods. def method_missing(sym, *args) @@ -104,14 +104,14 @@ # A collection of helper methods and resolvers # for relations. class Relation class << self - - # To avoid forward declarations, references to undefined + + # To avoid forward declarations, references to undefined # (at the time of the creation of the relation) classes are - # stored as symbols. These symbols are resolved by this + # stored as symbols. These symbols are resolved by this # method. #-- # FIXME: do something more elegant here. #++ @@ -152,175 +152,171 @@ # end def resolve_polymorphic_markers(klass) for r in klass.relations if r.polymorphic_marker? - r.owner_class.ann :this, :polymorphic => r.owner_class + r.owner_class.ann :self, :polymorphic => r.owner_class end end end # Resolve polymorphic relations. # If the target class is polymorphic, create a specialized - # version of that class (the target) enclosed in the + # version of that class (the target) enclosed in the # owner namespace. - # + # # For example: # # class Article # has_many Comment # ... # end - + def resolve_polymorphic_relations(klass) for r in klass.relations if r.polymorphic? - + target_dm = r.target_class.to_s.demodulize r.owner_class.module_eval %{ class #{r.owner_class}::#{target_dm} < #{r.target_class} end } - + # Replace the target class. - + r[:target_class] = eval("#{r.owner_class}::#{target_dm}") end - + r.resolve_polymorphic end end - + # Resolve the names of the relations. - + def resolve_names(klass) for r in klass.relations target_name = if r.collection :target_plural_name - else + else :target_singular_name end - + # Inflect the relation name. - + unless r[target_name] r[target_name] = if r.collection r.target_class.to_s.demodulize.underscore.downcase.plural.intern else r.target_class.to_s.demodulize.underscore.downcase.intern - end + end end - - r[:name] = r[target_name] + + r[:name] = r[target_name] end end - - # General resovle method. - + + # General resolve method. + def resolve(klass, action = :resolve_polymorphic) for r in klass.relations r.send(action) end end # Perform relation enchanting on this class. - - def enchant(klass) + + def enchant(klass) # update inherited relations. - + for r in klass.relations r[:owner_class] = klass end - - # enchant. - + + # enchant. + for r in klass.relations # p "=== #{klass} : #{r.class} : #{r.name}" r.enchant() unless r.polymorphic_marker? end - + end - + end end -# Relations domain specific language (DSL). This +# Relations domain specific language (DSL). This # language defines macros that are used to define Entity -# relations. Additional macros allow for relation +# relations. Additional macros allow for relation # inspection. module RelationDSL - def self.append_features(base) - super - base.module_eval do - inheritor(:relations, [], :+) unless @relations - end - base.extend(ClassMethods) - end - module ClassMethods + inheritor(:relations, [], :+) #unless @relations + class_inherit do + # === Examples # # belongs_to :article # inflects Article # belongs_to Article # inflects :article # belongs_to :article, Article # belongs_to :article, Article, :view => 'lala' - + def belongs_to(*args) require 'og/relation/belongs_to' relations! << Og::BelongsTo.new(args, :owner_class => self) end # === Examples # # refers_to :topic # inflects Topic # refers_to Topic # inflects :topic - + def refers_to(*args) require 'og/relation/refers_to' relations! << Og::RefersTo.new(args, :owner_class => self) end # === Examples # # has_one User - + def has_one(*args) require 'og/relation/has_one' relations! << Og::HasOne.new(args, :owner_class => self) end - + # === Examples # # has_many Comment # has_many :comments, Comment - + def has_many(*args) require 'og/relation/has_many' relations! << Og::HasMany.new(args, :owner_class => self, :collection => true) end # .. - + def joins_many(*args) require 'og/relation/joins_many' relations! << Og::JoinsMany.new(args, :owner_class => self, :collection => true) end - + # .. - + def many_to_many(*args) require 'og/relation/many_to_many' relations! << Og::ManyToMany.new(args, :owner_class => self, :collection => true) end def inspect_relation(name) relations.find { |r| r[:name] == name } end alias_method :relation, :inspect_relation - + end + end end # * George Moschovitis <gm@navel.gr> \ No newline at end of file