Module: Doodle::DoodleAttribute::ClassMethods

Included in:
Doodle::DoodleAttribute
Defined in:
lib/doodle/attribute.rb

Overview

note: using extend with a module causes an infinite loop in 1.9 hence the inline

Instance Method Summary collapse

Instance Method Details

#params_from_args(owner, *args) ⇒ Object

rewrite rules for the argument list to #has



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/doodle/attribute.rb', line 13

def params_from_args(owner, *args)
  Doodle::Debug.d { [owner, args] }
  key_values, positional_args = args.partition{ |x| x.kind_of?(Hash)}
  params = { }
  if positional_args.size > 0
    name = positional_args.shift
    case name
      # has Person --> has :person, :kind => Person
    when Class
      params[:name] = Utils.snake_case(name.to_s.split(/::/).last)
      params[:kind] = name
    else
      params[:name] = name.to_s.to_sym
    end
  end
  params = key_values.inject(params){ |acc, item| acc.merge(item)}
  #DBG: Doodle::Debug.d { [:has, self, self.class, params] }
  if !params.key?(:name)
    __doodle__.handle_error name, ArgumentError, "#{self.class} must have a name", Doodle::Utils.doodle_caller
    params[:name] = :__ERROR_missing_name__
  else
    # ensure that :name is a symbol
    params[:name] = params[:name].to_sym
  end
  name = params[:name]
  __doodle__.handle_error name, ArgumentError, "#{self.class} has too many arguments", Doodle::Utils.doodle_caller if positional_args.size > 0

  if collector = params.delete(:collect)
    if !params.key?(:using)
      if params.key?(:key)
        params[:using] = KeyedAttribute
      else
        params[:using] = AppendableAttribute
      end
    end
    # this in generic CollectorAttribute class
    # collector from(Hash)

    # TODO: rework this to allow multiple classes and mappings
    #p [:collector, collector, params, params[:init].kind_of?(Class)]
    # FIXME: collector
    if collector.kind_of?(Hash)
      collector_spec = collector
      #collector_name, collector_class = collector.to_a[0]
    elsif collector.kind_of?(Array) && collector.all? { |i| i.kind_of?(Hash) }
      collector_spec = collector.inject(OrderedHash.new) { |hash, item|
        item.keys.each do |key|
          hash[key] = item[key]
        end
        hash
      }
    else
      collectors = [collector].flatten
      collector_spec = collectors.inject(OrderedHash.new) do |hash, klass|
        collector_class = klass.to_s
        #p [:collector_klass, collector_klass]
        collector_name = Utils.snake_case(collector_class.split(/::/).last)
        #p [:collector_name, collector_class, collector_name]
        # FIXME: sanitize class name for 1.9 (make this a Utils function)
        collector_class = collector_class.gsub(/#<Class:0x[a-fA-F0-9]+>::/, '')
        # if Capitalized word given, treat as classname and create
        # collector for specific class
        if collector_class !~ /^[A-Z]/
          collector_class = nil
        end
        hash[collector_name] = collector_class
        hash
      end
      #!p [:collector_klass, collector_klass, params[:init]]
    end
    params[:collector_spec] = collector_spec
  end
  params[:doodle_owner] = owner
  #p [:params, owner, params]
  params
end