Module: Praxis::ResourceDefinition::ClassMethods

Defined in:
lib/praxis/resource_definition.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#actionsObject (readonly)

Returns the value of attribute actions.



70
71
72
# File 'lib/praxis/resource_definition.rb', line 70

def actions
  @actions
end

#controllerObject

Returns the value of attribute controller.



81
82
83
# File 'lib/praxis/resource_definition.rb', line 81

def controller
  @controller
end

#metadataObject (readonly)

opaque hash of user-defined medata, used to decorate the definition, and also available in the generated JSON documents



79
80
81
# File 'lib/praxis/resource_definition.rb', line 79

def 
  @metadata
end

#parent_prefixObject (readonly)

Returns the value of attribute parent_prefix.



75
76
77
# File 'lib/praxis/resource_definition.rb', line 75

def parent_prefix
  @parent_prefix
end

#responsesObject (readonly)

Returns the value of attribute responses.



71
72
73
# File 'lib/praxis/resource_definition.rb', line 71

def responses
  @responses
end

#routing_prefixObject



180
181
182
183
184
# File 'lib/praxis/resource_definition.rb', line 180

def routing_prefix
  return @routing_prefix if @routing_prefix

  @routing_prefix = parent_prefix + prefix
end

#traitsObject (readonly)

Returns the value of attribute traits.



73
74
75
# File 'lib/praxis/resource_definition.rb', line 73

def traits
  @traits
end

#version_optionsObject (readonly)

Returns the value of attribute version_options.



72
73
74
# File 'lib/praxis/resource_definition.rb', line 72

def version_options
  @version_options
end

#version_prefixObject (readonly)

Returns the value of attribute version_prefix.



74
75
76
# File 'lib/praxis/resource_definition.rb', line 74

def version_prefix
  @version_prefix
end

Instance Method Details

#action(name, &block) ⇒ Object

Raises:

  • (ArgumentError)


285
286
287
288
289
# File 'lib/praxis/resource_definition.rb', line 285

def action(name, &block)
  raise ArgumentError, "can not create ActionDefinition without block" unless block_given?
  raise ArgumentError, "Action names must be defined using symbols (Got: #{name} (of type #{name.class}))" unless name.is_a? Symbol
  @actions[name] = ActionDefinition.new(name, self, &block)
end

#action_defaults(&block) ⇒ Object



249
250
251
252
253
254
255
# File 'lib/praxis/resource_definition.rb', line 249

def action_defaults(&block)
  if block_given?
    @action_defaults.instance_eval(&block)
  end

  @action_defaults
end

#canonical_path(action_name = nil) ⇒ Object



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/praxis/resource_definition.rb', line 206

def canonical_path(action_name=nil)
  if action_name
    raise "Canonical path for #{self.name} is already defined as: '#{@canonical_action_name}'. 'canonical_path' can only be defined once." if @canonical_action_name
    @canonical_action_name = action_name
  else
    # Resolution of the actual action definition needs to be done lazily, since we can use the `canonical_path` stanza
    # at the top of the resource, well before the actual action is defined.
    unless @canonical_action
      href_action = @canonical_action_name || DEFAULT_RESOURCE_HREF_ACTION
      @canonical_action = actions.fetch(href_action) do
        raise "Error: trying to set canonical_href of #{self.name}. Action '#{href_action}' does not exist"
      end
    end
    return @canonical_action
  end
end

#describe(context: nil) ⇒ Object



300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/praxis/resource_definition.rb', line 300

def describe(context: nil)
  {}.tap do |hash|
    hash[:description] = description
    hash[:media_type] = media_type.describe(true) if media_type
    hash[:actions] = actions.values.collect{|action| action.describe(context: context)}
    hash[:name] = self.name
    hash[:parent] = self.parent.id if self.parent
    hash[:display_name] = self.display_name
    hash[:metadata] = 
    hash[:traits] = self.traits
  end
end

#description(text = nil) ⇒ Object



291
292
293
294
# File 'lib/praxis/resource_definition.rb', line 291

def description(text=nil)
  @description = text if text
  @description
end

#display_name(string = nil) ⇒ Object



83
84
85
86
87
88
# File 'lib/praxis/resource_definition.rb', line 83

def display_name( string=nil )
  unless string
    return  @display_name ||= self.name.split("::").last  # Best guess at a display name?
  end
  @display_name = string
end

#headers(**opts, &block) ⇒ Object



271
272
273
274
275
276
# File 'lib/praxis/resource_definition.rb', line 271

def headers(**opts, &block)
  warn 'DEPRECATED: ResourceDefinition.headers is deprecated. Use action_defaults instead.'
  action_defaults do
    headers **opts, &block
  end
end

#idObject



296
297
298
# File 'lib/praxis/resource_definition.rb', line 296

def id
  self.name.gsub('::'.freeze,'-'.freeze)
end

#inherit_params_from_parent(parent_action, **mapping) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/praxis/resource_definition.rb', line 163

def inherit_params_from_parent(parent_action, **mapping)
  actions.each do |name, action|
    action.params do
      mapping.each do |parent_name, name|
        next if action.params && action.params.attributes.key?(name)

        parent_attribute = parent_action.params.attributes[parent_name]

        attribute name, parent_attribute.type, parent_attribute.options
      end
    end
  end

end

#media_type(media_type = nil) ⇒ Object



112
113
114
115
116
117
118
119
# File 'lib/praxis/resource_definition.rb', line 112

def media_type(media_type=nil)
  return @media_type if media_type.nil?

  if media_type.kind_of?(String)
    media_type = SimpleMediaType.new(media_type)
  end
  @media_type = media_type
end

#nodoc!Object



313
314
315
# File 'lib/praxis/resource_definition.rb', line 313

def nodoc!
  [:doc_visibility] = :none
end

#on_finalizeObject



90
91
92
93
94
95
96
# File 'lib/praxis/resource_definition.rb', line 90

def on_finalize
  if block_given?
    @on_finalize << Proc.new
  end

  @on_finalize
end

#params(type = Attributor::Struct, **opts, &block) ⇒ Object



257
258
259
260
261
262
# File 'lib/praxis/resource_definition.rb', line 257

def params(type=Attributor::Struct, **opts, &block)
  warn 'DEPRECATED: ResourceDefinition.params is deprecated. Use it in action_defaults instead.'
  action_defaults do
    params type, **opts, &block
  end
end

#parent(parent = nil, **mapping) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/praxis/resource_definition.rb', line 122

def parent(parent=nil, **mapping)
  return @parent if parent.nil?

  @routing_prefix = nil # reset routing_prefix

  parent_action = parent.canonical_path
  parent_route = parent_action.primary_route.path

  # if a mapping is passed, it *must* resolve any param name conflicts
  unless mapping.any?
    # assume last capture is the relevant one to replace
    # if not... then I quit.
    parent_param_name = parent_route.names.last

    # more assumptions about names
    parent_name = parent.name.demodulize.underscore.singularize

    # put it together to find what we should call this new param
    param = "#{parent_name}_#{parent_param_name}".to_sym
    mapping[parent_param_name.to_sym] = param
  end

  # complete the mapping and massage the route
  parent_route.names.collect(&:to_sym).each do |name|
    if mapping.key?(name)
      param = mapping[name]
      # FIXME: this won't handle URI Template type paths, ie '/{parent_id}'
      prefixed_path = parent_action.primary_route.prefixed_path
      @parent_prefix = prefixed_path.gsub(/(:)(#{name})(\W+|$)/, "\\1#{param.to_s}\\3")
    else
      mapping[name] = name
    end
  end

  self.on_finalize do
    self.inherit_params_from_parent(parent_action, **mapping)
  end

  @parent = parent
end

#parse_href(path) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/praxis/resource_definition.rb', line 227

def parse_href(path)
  if path.kind_of?(::URI::Generic)
    path = path.path
  end
  param_values = canonical_path.primary_route.path.params(path)
  attrs = canonical_path.params.attributes
  param_values.each_with_object({}) do |(key,value),hash|
    hash[key.to_sym] = attrs[key.to_sym].load(value,[key])
  end
rescue => e
  raise Praxis::Exception.new("Error parsing or coercing parameters from href: #{path}\n"+e.message)
end

#payload(type = Attributor::Struct, **opts, &block) ⇒ Object



264
265
266
267
268
269
# File 'lib/praxis/resource_definition.rb', line 264

def payload(type=Attributor::Struct, **opts, &block)
  warn 'DEPRECATED: ResourceDefinition.payload is deprecated. Use action_defaults instead.'
  action_defaults do
    payload type, **opts, &block
  end
end

#prefix(prefix = nil) ⇒ Object



106
107
108
109
110
# File 'lib/praxis/resource_definition.rb', line 106

def prefix(prefix=nil)
  return @prefix if prefix.nil?
  @routing_prefix = nil # reset routing_prefix
  @prefix = prefix
end

#response(name, **args) ⇒ Object



278
279
280
281
282
283
# File 'lib/praxis/resource_definition.rb', line 278

def response(name, **args)
  warn 'DEPRECATED: ResourceDefinition.response is deprecated. Use action_defaults instead.'
  action_defaults do
    response name, **args
  end
end

#routing(&block) ⇒ Object

FIXME: this is inconsistent with the rest of the magic DSL convention.



99
100
101
102
103
104
# File 'lib/praxis/resource_definition.rb', line 99

def routing(&block)
  warn "DEPRECATED: ResourceDefinition.routing is deprecated use prefix directly instead."

  # eval this assuming it will only call #prefix
  self.instance_eval(&block)
end

#to_href(params) ⇒ Object



223
224
225
# File 'lib/praxis/resource_definition.rb', line 223

def to_href( params )
  canonical_path.primary_route.path.expand(params)
end

#trait(trait_name) ⇒ Object Also known as: use



240
241
242
243
244
245
246
# File 'lib/praxis/resource_definition.rb', line 240

def trait(trait_name)
  unless ApiDefinition.instance.traits.has_key? trait_name
    raise Exceptions::InvalidTrait.new("Trait #{trait_name} not found in the system")
  end
  trait = ApiDefinition.instance.traits.fetch(trait_name)
  @traits << trait_name
end

#version(version = nil, options = nil) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/praxis/resource_definition.rb', line 187

def version(version=nil, options=nil)
  return @version unless version

  @version = version

  unless options.nil?
    warn 'DEPRECATED: ResourceDefinition.version with options is no longer supported. Define in api global info instead.'

    @version_options = options
    version_using = Array(@version_options[:using])
    if version_using.include?(:path)
      @version_prefix = "#{Praxis::Request::path_version_prefix}#{self.version}"
    end
  end

  @action_defaults.instance_eval &ResourceDefinition.generate_defaults_block( version: version )
end