lib/og/relation.rb in og-0.20.0 vs lib/og/relation.rb in og-0.21.0
- old
+ new
@@ -7,228 +7,252 @@
# A relation between Entities.
class Relation
- attr_accessor :options
-
- attr_accessor :is_polymorphic
-
- # 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)
+ attr_accessor :options
+
+ attr_accessor :is_polymorphic
+
+ # 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)
- if args.empty? or (not (args.last.is_a?(Class) or args.last.is_a?(Symbol)))
- raise 'Class of target not defined'
- end
+ if args.empty? or (not (args.last.is_a?(Class) or args.last.is_a?(Symbol)))
+ raise 'Class of target not defined'
+ end
- @options[:target_class] = args.pop
+ @options[:target_class] = args.pop
- if target_class == Object
- # If the target class is just an Object mark that class
- # as a polymorphic parent class.
- # This class acts as template
- # to generate customized versions of this class.
+ if target_class == Object
+ # If the target class is just an Object mark that class
+ # as a polymorphic parent class.
+ # This class acts as template
+ # to generate customized versions of this class.
- owner_class.meta(:polymorphic, owner_class)
- elsif target_class.respond_to?(:metadata) and target_class.metadata.polymorphic
- # If the target class is polymorphic, create a specialized
- # version of the class enclosed in the owner namespace.
-
- target_dm = target_class.to_s.demodulize
- owner_class.module_eval %{
- class #{owner_class}::#{target_dm} < #{target_class}
- end
- }
- eval %{
- @options[:target_class] = #{owner_class}::#{target_dm}
- }
- end
-
- target_name = if collection
- :target_plural_name
- else
- :target_singular_name
- end
-
- # Inflect the relation name.
-
- unless args.empty?
- @options[target_name] = args.first
- else
- @options[target_name] = if collection
- target_class.to_s.demodulize.underscore.downcase.plural.intern
- else
- target_class.to_s.demodulize.underscore.downcase.intern
- end
- end
-
- @options[:name] = options[target_name]
- end
+ owner_class.meta(:polymorphic, owner_class)
+ elsif target_class.respond_to?(:metadata) and target_class.metadata.polymorphic
+ # If the target class is polymorphic, create a specialized
+ # version of the class enclosed in the owner namespace.
+
+ target_dm = target_class.to_s.demodulize
+ owner_class.module_eval %{
+ class #{owner_class}::#{target_dm} < #{target_class}
+ end
+ }
+ eval %{
+ @options[:target_class] = #{owner_class}::#{target_dm}
+ }
+ end
+
+ target_name = if collection
+ :target_plural_name
+ else
+ :target_singular_name
+ end
+
+ # Inflect the relation name.
+
+ unless args.empty?
+ @options[target_name] = args.first
+ else
+ @options[target_name] = if collection
+ target_class.to_s.demodulize.underscore.downcase.plural.intern
+ else
+ target_class.to_s.demodulize.underscore.downcase.intern
+ end
+ end
+
+ @options[:name] = options[target_name]
+ end
- def [](key)
- @options[key]
- end
+ def [](key)
+ @options[key]
+ end
- def []=(key, val)
- @options[key] = val
- end
+ def []=(key, val)
+ @options[key] = val
+ end
- # Is the relation polymorphic?
-
- def polymorphic?
- target_class == Object
- end
+ # Is the relation polymorphic?
+
+ def polymorphic?
+ target_class == Object
+ end
- #--
- # gmosx, TODO: remove, this is not really needed.
- #++
-
- def resolve_options
- @options[:owner_pk], @options[:owner_pkclass] = owner_class.primary_key
- if target_class.respond_to?(:primary_key)
- @options[:target_pk], @options[:target_pkclass] = target_class.primary_key
- end
- end
+ #--
+ # gmosx, TODO: remove, this is not really needed.
+ #++
+
+ def resolve_options
+ @options[:owner_pk], @options[:owner_pkclass] = owner_class.primary_key
+ if target_class.respond_to?(:primary_key)
+ @options[:target_pk], @options[:target_pkclass] = target_class.primary_key
+ end
+ end
- # 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
- # method.
- #--
- # FIXME: do something more elegant here.
- #++
+ # 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
+ # method.
+ #--
+ # FIXME: do something more elegant here.
+ #++
- def resolve_target
- if target_class.is_a?(Symbol)
- c = owner_class.name.dup
- c = "::" + c unless c =~ /::/
- c.gsub!(/::.*$/, '::')
- c << target_class.to_s
- begin
- klass = constant(c)
- rescue
- unless c == target_class
- c = target_class
- retry
- end
- end
- @options[:target_class] = klass
- end
- end
+ def resolve_symbol(sym, owner_class)
+ c = owner_class.name.dup
+ c = "::" + c unless c =~ /::/
+ c.gsub!(/::.*$/, '::')
+ c << sym.to_s
+ begin
+ return constant(c)
+ rescue
+ unless c == sym
+ c = sym
+ retry
+ end
+ end
+ end
- # Resolve a polymorphic target class.
- # Overrided in subclasses.
-
- def resolve_polymorphic
- end
-
- # This method is implemented in subclasses.
-
- def enchant
- end
+ def resolve_target
+ if target_class.is_a?(Symbol)
+ klass = resolve_symbol(target_class, owner_class)
+ @options[:target_class] = klass
+ end
+ end
+
+=begin
+ def resolve_target
+ if target_class.is_a?(Symbol)
+ c = owner_class.name.dup
+ c = "::" + c unless c =~ /::/
+ c.gsub!(/::.*$/, '::')
+ c << target_class.to_s
+ begin
+ klass = constant(c)
+ rescue
+ unless c == target_class
+ c = target_class
+ retry
+ end
+ end
+ @options[:target_class] = klass
+ end
+ end
+=end
- # Access the hash values as methods.
+ # Resolve a polymorphic target class.
+ # Overrided in subclasses.
+
+ def resolve_polymorphic
+ end
+
+ # This method is implemented in subclasses.
+
+ def enchant
+ end
- def method_missing(sym, *args)
- return @options[sym]
- end
+ # Access the hash values as methods.
- class << self
+ def method_missing(sym, *args)
+ return @options[sym]
+ end
- def resolve(klass, action)
- if klass.__meta[:relations]
- for relation in klass.__meta[:relations]
- relation.send(action)
- end
- end
- end
-
- def enchant(klass)
- if klass.__meta[:relations]
- for relation in klass.__meta[:relations]
- relation.enchant unless relation.target_class == Object
- end
- end
- end
+ class << self
- end
+ def resolve(klass, action)
+ if klass.__meta[:relations]
+ for relation in klass.__meta[:relations]
+ relation.send(action)
+ end
+ end
+ end
+
+ def enchant(klass)
+ if klass.__meta[:relations]
+ for relation in klass.__meta[:relations]
+ relation.enchant unless relation.target_class == Object
+ end
+ end
+ end
+ end
+
end
# Relation macros. These macros are used to define Entity
# relations.
module RelationMacros
- def self.append_features(base)
- super
- base.extend(ClassMethods)
- end
+ def self.append_features(base)
+ super
+ base.extend(ClassMethods)
+ end
- module ClassMethods
+ module ClassMethods
- # === Examples
- #
- # belongs_to Article
- # belongs_to :article, Article
- # belongs_to :article, Article, :view => 'lala'
-
- def belongs_to(*args)
- require 'og/relation/belongs_to'
- meta :relations, Og::BelongsTo.new(args, :owner_class => self)
- end
+ # === Examples
+ #
+ # belongs_to Article
+ # belongs_to :article, Article
+ # belongs_to :article, Article, :view => 'lala'
+
+ def belongs_to(*args)
+ require 'og/relation/belongs_to'
+ meta :relations, Og::BelongsTo.new(args, :owner_class => self)
+ end
- # === Examples
- #
- # refers_to Topic
-
- def refers_to(*args)
- require 'og/relation/refers_to'
- meta :relations, Og::RefersTo.new(args, :owner_class => self)
- end
+ # === Examples
+ #
+ # refers_to Topic
+
+ def refers_to(*args)
+ require 'og/relation/refers_to'
+ meta :relations, Og::RefersTo.new(args, :owner_class => self)
+ end
- # === Examples
- #
- # has_one User
-
- def has_one(*args)
- require 'og/relation/has_one'
- meta :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'
- meta :relations, Og::HasMany.new(args, :owner_class => self, :collection => true)
- end
+ # === Examples
+ #
+ # has_one User
+
+ def has_one(*args)
+ require 'og/relation/has_one'
+ meta :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'
+ meta :relations, Og::HasMany.new(args, :owner_class => self, :collection => true)
+ end
- def joins_many(*args)
- require 'og/relation/joins_many'
- meta :relations, Og::JoinsMany.new(args, :owner_class => self, :collection => true)
- end
-
- def many_to_many(*args)
- require 'og/relation/many_to_many'
- meta :relations, Og::ManyToMany.new(args, :owner_class => self, :collection => true)
- end
+ def joins_many(*args)
+ require 'og/relation/joins_many'
+ meta :relations, Og::JoinsMany.new(args, :owner_class => self, :collection => true)
+ end
+
+ def many_to_many(*args)
+ require 'og/relation/many_to_many'
+ meta :relations, Og::ManyToMany.new(args, :owner_class => self, :collection => true)
+ end
- def inspect_relations
- __meta[:relations]
- end
- alias_method :relations, :inspect_relations
+ def inspect_relations
+ __meta[:relations]
+ end
+ alias_method :relations, :inspect_relations
- def inspect_relation(name)
- __meta[:relations].find { |r| r[:name] == name }
- end
- alias_method :relation, :inspect_relation
-
- end
+ def inspect_relation(name)
+ __meta[:relations].find { |r| r[:name] == name }
+ end
+ alias_method :relation, :inspect_relation
+
+ end
end
end