Class: FlexibleApi::RequestLevel

Inherits:
Object
  • Object
show all
Defined in:
lib/flexible_api/request_level.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, klass) ⇒ RequestLevel

Returns a new instance of RequestLevel.



5
6
7
8
9
10
11
12
13
14
15
# File 'lib/flexible_api/request_level.rb', line 5

def initialize(name, klass)
  @name = name
  @klass = klass
  @display_fields = Set.new
  @select_fields = Set.new
  @scopes = []
  @includes = []
  @notations = {}
  @eaten_levels = []
  @select_fields << "`#{@klass.table_name}`.#{@klass.primary_key}" # auto-select primary key
end

Instance Attribute Details

#display_fieldsObject (readonly)

Returns the value of attribute display_fields.



17
18
19
# File 'lib/flexible_api/request_level.rb', line 17

def display_fields
  @display_fields
end

#nameObject (readonly)

Returns the value of attribute name.



17
18
19
# File 'lib/flexible_api/request_level.rb', line 17

def name
  @name
end

#notationsObject (readonly)

Returns the value of attribute notations.



17
18
19
# File 'lib/flexible_api/request_level.rb', line 17

def notations
  @notations
end

Instance Method Details

#all_fieldsObject



82
83
84
# File 'lib/flexible_api/request_level.rb', line 82

def all_fields
  fields *@klass.columns_hash.keys.map(&:to_sym)
end

#display_fieldObject



117
118
119
120
121
122
123
# File 'lib/flexible_api/request_level.rb', line 117

def display_field
  @display_field_array ||= begin
    displays = @display_fields.to_a
    @eaten_levels.each { |l| displays.concat l.display_field }
    displays
  end
end

#eat_level(name) ⇒ Object



29
30
31
# File 'lib/flexible_api/request_level.rb', line 29

def eat_level(name)
  @eaten_levels << @klass.find_level(name)
end

#fields(*field_array) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/flexible_api/request_level.rb', line 86

def fields(*field_array)
  field_array.each do |field|
    if field.is_a?(String)
      @display_fields << field.split('.').last.to_sym
      @select_fields << field
    else
      @display_fields << field
      @select_fields << "`#{@klass.table_name}`.#{field}" if @klass.columns_hash.keys.include?(field.to_s)
    end
  end
end

#include_fieldObject



125
126
127
128
129
130
131
# File 'lib/flexible_api/request_level.rb', line 125

def include_field
  @include_field_array ||= begin
    includes = @includes.map { |i| i[:association].name }
    @eaten_levels.each { |l| includes.concat l.include_field }
    includes
  end
end

#includes(association_name, options = {}) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/flexible_api/request_level.rb', line 58

def includes(association_name, options = {})
  options.assert_valid_keys :request_level, :as, :requires
  association = @klass.reflect_on_all_associations.detect { |a| a.name == association_name.to_sym }
  raise "No such association on #{@klass.name}: #{association_name}" if association.nil? # TODO
  # Allow requires to pass in
  requires *options[:requires] if options.has_key?(:requires)
  # Set the include options
  @includes << { 
    :name => options[:as] || association_name,
    :association => association, 
    :request_level => association.klass.find_level(options[:request_level])
  }
end

#method(method_name, options = {}) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/flexible_api/request_level.rb', line 43

def method(method_name, options = {})
  options.assert_valid_keys :request_level, :as, :requires
  method = @klass.instance_methods.detect { |m| m == method_name.to_sym }
  raise "No such method on #{@klass.name}: #{method_name}" if method.nil?
  notation_options = (options.has_key?(:requires) ? {:requires => options[:requires]} : {})
  notation(options[:as] || method_name, notation_options) do
    (method_contents = self.send(method_name)) or next
    if method_contents.is_a?(Array)
      method_contents.map {|content| content.to_hash(options[:request_level]) }
    else
      method_contents.to_hash(options[:request_level])
    end        
  end    
end

#notation(notation_name, options = {}, &block) ⇒ Object



37
38
39
40
41
# File 'lib/flexible_api/request_level.rb', line 37

def notation(notation_name, options = {}, &block)
  options.assert_valid_keys :requires
  requires *options[:requires]
  @notations[notation_name] = block
end

#receive(item) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/flexible_api/request_level.rb', line 133

def receive(item)
  return nil if item.nil? # method may be nil
  attributes = {}
  @eaten_levels.each do |level|
    attributes.merge! level.receive(item)
  end
  @display_fields.each do |field|
    attributes[field] = item.send(field)
  end
  @includes.each do |include|
    value = item.send(include[:association].name)
    value = value.is_a?(Enumerable) ? value.map { |e| include[:request_level].receive(e) } : include[:request_level].receive(value)
    attributes[include[:name]] = value
  end
  @notations.each do |name, block|
    attributes[name] = item.instance_eval(&block)
  end
  attributes
end

#requires(*requires_array) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'lib/flexible_api/request_level.rb', line 72

def requires(*requires_array)
  requires_array.each do |field|
    if field.is_a?(String)
      @select_fields << field
    else
      @select_fields << "`#{@klass.table_name}`.#{field}" if @klass.columns_hash.keys.include?(field.to_s)
    end
  end
end

#scope(name, args = nil) ⇒ Object



33
34
35
# File 'lib/flexible_api/request_level.rb', line 33

def scope(name, args = nil)
  @scopes << [name, args]
end

#scope_fieldObject



100
101
102
103
104
105
106
107
# File 'lib/flexible_api/request_level.rb', line 100

def scope_field
  @scopes_array ||= begin
    scopes = []
    scopes.concat @scopes
    @eaten_levels.each { |l| scopes.concat l.scope_field }
    scopes
  end
end

#select_fieldObject



109
110
111
112
113
114
115
# File 'lib/flexible_api/request_level.rb', line 109

def select_field
  @select_field_array ||= begin
    selects = @select_fields.to_a
    @eaten_levels.each { |l| selects.concat l.select_field }
    selects
  end
end

#to_hashObject



19
20
21
22
23
24
25
26
27
# File 'lib/flexible_api/request_level.rb', line 19

def to_hash
  {
    :name => @name,
    :fields => display_field + notations.keys,
    :includes => @includes.map do |inc|
      { :name => inc[:name], :type => inc[:association].name.to_s.pluralize.underscore.downcase, :request_level => inc[:request_level].name }
    end
  }
end