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