Class: Smooth::Resource

Inherits:
Object show all
Includes:
Documentation, Templating
Defined in:
lib/smooth/resource.rb,
lib/smooth/resource/router.rb,
lib/smooth/resource/tracking.rb,
lib/smooth/resource/templating.rb

Defined Under Namespace

Modules: Templating, Tracking Classes: Router

Constant Summary

Constants included from Templating

Templating::FakerGroups

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Templating

#build_from_template, #create_from_template, fakers, #template, #template_registered?, #templates

Methods included from Documentation

#desc, included, #inline_description

Constructor Details

#initialize(resource_name, options = {}, &block) ⇒ Resource

Returns a new instance of Resource.



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
# File 'lib/smooth/resource.rb', line 23

def initialize(resource_name, options = {}, &block)
  @resource_name  = resource_name
  @options        = options

  @model_class    = options.fetch(:model, nil)

  @_serializers   = {}.to_mash
  @_commands      = {}.to_mash
  @_queries       = {}.to_mash
  @_routes        = {}.to_mash
  @_examples      = {}.to_mash

  @object_descriptions = {
    commands: {},
    queries: {},
    serializers: {},
    routes: {},
    examples: {}
  }

  @loaded         = false

  instance_eval(&block) if block_given?

  load!
end

Instance Attribute Details

#_commandsObject (readonly)

These store the configuration values for the various objects belonging to the resource.



16
17
18
# File 'lib/smooth/resource.rb', line 16

def _commands
  @_commands
end

#_examplesObject (readonly)

These store the configuration values for the various objects belonging to the resource.



16
17
18
# File 'lib/smooth/resource.rb', line 16

def _examples
  @_examples
end

#_queriesObject (readonly)

These store the configuration values for the various objects belonging to the resource.



16
17
18
# File 'lib/smooth/resource.rb', line 16

def _queries
  @_queries
end

#_routesObject (readonly)

These store the configuration values for the various objects belonging to the resource.



16
17
18
# File 'lib/smooth/resource.rb', line 16

def _routes
  @_routes
end

#_serializersObject (readonly)

These store the configuration values for the various objects belonging to the resource.



16
17
18
# File 'lib/smooth/resource.rb', line 16

def _serializers
  @_serializers
end

#api_nameObject

Returns the value of attribute api_name.



8
9
10
# File 'lib/smooth/resource.rb', line 8

def api_name
  @api_name
end

#descriptionObject

Returns the value of attribute description.



8
9
10
# File 'lib/smooth/resource.rb', line 8

def description
  @description
end

#group_descriptionObject

Returns the value of attribute group_description.



8
9
10
# File 'lib/smooth/resource.rb', line 8

def group_description
  @group_description
end

#model_classObject

Returns the value of attribute model_class.



8
9
10
# File 'lib/smooth/resource.rb', line 8

def model_class
  @model_class
end

#object_descriptionsObject (readonly)

These store the configuration values for the various objects belonging to the resource.



16
17
18
# File 'lib/smooth/resource.rb', line 16

def object_descriptions
  @object_descriptions
end

#resource_nameObject

Returns the value of attribute resource_name.



8
9
10
# File 'lib/smooth/resource.rb', line 8

def resource_name
  @resource_name
end

Instance Method Details

#apiObject



149
150
151
# File 'lib/smooth/resource.rb', line 149

def api
  Smooth.fetch_api(api_name || :default)
end

#apply_options(*opts) ⇒ Object



153
154
155
# File 'lib/smooth/resource.rb', line 153

def apply_options(*opts)
  @options.send(:merge!, *opts)
end

#available_commandsObject



80
81
82
# File 'lib/smooth/resource.rb', line 80

def available_commands
  _commands.keys
end

#available_examplesObject



97
98
99
# File 'lib/smooth/resource.rb', line 97

def available_examples
  _examples.keys
end

#available_queriesObject



84
85
86
# File 'lib/smooth/resource.rb', line 84

def available_queries
  _queries.keys
end

#available_routesObject

SHORT CIRCUIT



93
94
95
# File 'lib/smooth/resource.rb', line 93

def available_routes
  []
end

#available_serializersObject



88
89
90
# File 'lib/smooth/resource.rb', line 88

def available_serializers
  _serializers.keys
end

#belongs_to(*args) ⇒ Object



113
114
115
# File 'lib/smooth/resource.rb', line 113

def belongs_to(*args)
  model_class.send(:belongs_to, *args)
end

#command(command_name, *args, &block) ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/smooth/resource.rb', line 202

def command(command_name, *args, &block)
  if args.empty? && !block_given? && exists = fetch(:command, command_name)
    return exists
  end

  options = args.extract_options!

  provided_description = options.fetch(:description, inline_description)

  describe_object(:command, command_name.downcase, provided_description) unless provided_description.empty?

  specified_class = args.first
  specified_class = (specified_class.constantize rescue nil) if specified_class.is_a?(String)
  specified_class = nil if specified_class && !(specified_class <= Smooth.config.command_class)

  config = _commands[command_name.to_sym] ||= Hashie::Mash.new(options: {}, name: command_name, blocks: [block].compact, class: specified_class)

  config.options.merge!(options)
  config.description = provided_description unless provided_description.nil?

  config
end

#command_classesObject



298
299
300
# File 'lib/smooth/resource.rb', line 298

def command_classes
  @commands && @commands.values
end

#describe_object(object_type, object_name, with_value = {}) ⇒ Object



157
158
159
160
161
162
163
164
# File 'lib/smooth/resource.rb', line 157

def describe_object(object_type, object_name, with_value = {})
  bucket = documentation_for(object_type, object_name)

  with_value = { description: with_value } if with_value.is_a?(String)

  bucket[:description] = with_value.fetch(:description, with_value['description'])
  bucket[:description_args] = with_value.fetch(:args, [])
end

#documentation_for(object_type, object_name) ⇒ Object



166
167
168
# File 'lib/smooth/resource.rb', line 166

def documentation_for(object_type, object_name)
  object_descriptions[object_type.to_s.pluralize.to_sym][object_name.to_sym] ||= {}
end

#examples(options = {}, &_block) ⇒ Object



276
277
278
279
280
# File 'lib/smooth/resource.rb', line 276

def examples(options = {}, &_block)
  if options.empty? && !block_given?
    return @examples
  end
end

#expand_routes(from_attributes = {}) ⇒ Object



272
273
274
# File 'lib/smooth/resource.rb', line 272

def expand_routes(from_attributes = {})
  router.expand_routes(from_attributes)
end

#expanded_documentation_for(object_type, object_name) ⇒ Object



170
171
172
173
174
175
# File 'lib/smooth/resource.rb', line 170

def expanded_documentation_for(object_type, object_name)
  base = documentation_for(object_type, object_name)
  klass = object_class_for(object_type, object_name)

  base.merge!(class: klass.to_s, interface: klass && klass.interface_documentation)
end

#fetch(object_type, object_key) ⇒ Object



131
132
133
134
135
# File 'lib/smooth/resource.rb', line 131

def fetch(object_type, object_key)
  source = instance_variable_get("@#{ object_type }s") rescue nil
  source = @queries if object_type.to_sym == :query
  source && source.fetch(object_key.to_s.downcase)
end

#fetch_config(object_type, object_key) ⇒ Object



125
126
127
128
129
# File 'lib/smooth/resource.rb', line 125

def fetch_config(object_type, object_key)
  source = send("_#{ object_type }s") rescue nil
  source = @_queries if object_type.to_sym == :query
  source && source.fetch(object_key.to_s.downcase.to_sym)
end

#has_and_belongs_to_many(*args) ⇒ Object



121
122
123
# File 'lib/smooth/resource.rb', line 121

def has_and_belongs_to_many(*args)
  model_class.send(:has_and_belongs_to_many, *args)
end

#has_many(*args) ⇒ Object



109
110
111
# File 'lib/smooth/resource.rb', line 109

def has_many(*args)
  model_class.send(:has_many, *args)
end

#has_one(*args) ⇒ Object



117
118
119
# File 'lib/smooth/resource.rb', line 117

def has_one(*args)
  model_class.send(:has_one, *args)
end

#interface_documentationObject

The Smooth Resources are capable of exposing information about their configuration, which makes auto generating documentation for their API very easy, but this can also be used to generate client side models or control form / report builder interfaces.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/smooth/resource.rb', line 54

def interface_documentation
  resource = self

  @interface ||= begin
                   base = {
                     routes: (router.interface_documentation rescue {})
                   }

                   resource.object_descriptions.keys.reduce(base) do |memo, type|
                     memo.tap do
                       bucket = memo[type] ||= {}
                       resource.send("available_#{ type }").each do |object_name|
                         docs = resource.expanded_documentation_for(type, object_name)
                         bucket[object_name] = docs
                       end
                     end
                   end
                 end.to_mash
end

#load!Object



141
142
143
144
145
146
147
# File 'lib/smooth/resource.rb', line 141

def load!
  configure_commands
  configure_serializers
  configure_queries
  configure_routes
  configure_examples
end

#loaded?Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/smooth/resource.rb', line 137

def loaded?
  !!@loaded
end

#model(&block) ⇒ Object



256
257
258
# File 'lib/smooth/resource.rb', line 256

def model(&block)
  model_class.instance_eval(&block)
end

#nameObject



105
106
107
# File 'lib/smooth/resource.rb', line 105

def name
  resource_name
end

#object_class_for(object_type, object_name) ⇒ Object



177
178
179
180
181
# File 'lib/smooth/resource.rb', line 177

def object_class_for(object_type, object_name)
  fetch(object_type.to_s.singularize.to_sym, object_name.to_sym)
rescue => e
  binding.pry
end

#part_of_the(group_description) ⇒ Object

Resource groups allow for easier organization of the documentation and things of that nature.



76
77
78
# File 'lib/smooth/resource.rb', line 76

def part_of_the(group_description)
  @group_description = group_description
end

#query(query_name = 'Default', *args, &block) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/smooth/resource.rb', line 225

def query(query_name = 'Default', *args, &block)
  if args.empty? && !block_given? && exists = fetch(:query, query_name)
    return exists
  end

  options = args.extract_options!

  provided_description = options.fetch(:description, inline_description)

  describe_object(:query, query_name.downcase, provided_description) unless provided_description.empty?

  specified_class = args.first
  specified_class = (specified_class.constantize rescue nil) if specified_class.is_a?(String)
  specified_class = nil if specified_class && !(specified_class <= Smooth.config.query_class)

  config = _queries[query_name.downcase.to_sym] ||= Hashie::Mash.new(options: {}, name: query_name, blocks: [block].compact, class: specified_class)
  config.options.merge!(options)
  config.description = provided_description unless provided_description.nil?

  config
end

#query_class(reference = :default) ⇒ Object



286
287
288
# File 'lib/smooth/resource.rb', line 286

def query_class(reference = :default)
  @queries.fetch(reference, query_classes.first)
end

#query_classesObject



294
295
296
# File 'lib/smooth/resource.rb', line 294

def query_classes
  @queries && @queries.values
end

#route_tableObject



268
269
270
# File 'lib/smooth/resource.rb', line 268

def route_table
  router.route_table
end

#routerObject



264
265
266
# File 'lib/smooth/resource.rb', line 264

def router
  @router || routes
end

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



247
248
249
250
251
252
253
254
# File 'lib/smooth/resource.rb', line 247

def routes(options = {}, &block)
  return @router unless block_given?

  @router ||= Smooth::Resource::Router.new(self, options).tap do |router|
    router.instance_eval(&block)
    router.build_methods_table
  end
end

#scope(*args, &block) ⇒ Object



260
261
262
# File 'lib/smooth/resource.rb', line 260

def scope(*args, &block)
  model_class.send(:scope, *args, &block)
end

#serializer(serializer_name = 'Default', *args, &block) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/smooth/resource.rb', line 183

def serializer(serializer_name = 'Default', *args, &block)
  if args.empty? && !block_given? && exists = fetch(:serializer, serializer_name)
    return exists
  end

  options = args.extract_options!

  provided_description = options.fetch(:description, inline_description)

  describe_object(:serializer, serializer_name.downcase, provided_description) unless provided_description.empty?

  specified_class = args.first
  specified_class = specified_class.constantize if specified_class.is_a?(String)
  specified_class = nil if specified_class && !(specified_class <= Smooth.config.serializer_class)

  config = _serializers[serializer_name.downcase.to_sym] ||= Hashie::Mash.new(options: {}, name: serializer_name, blocks: [block].compact, class: specified_class)
  config.description = provided_description unless provided_description.nil?
end

#serializer_class(reference = :default) ⇒ Object



282
283
284
# File 'lib/smooth/resource.rb', line 282

def serializer_class(reference = :default)
  @serializers.fetch(reference, serializer_classes.first)
end

#serializer_classesObject



290
291
292
# File 'lib/smooth/resource.rb', line 290

def serializer_classes
  @serializers && @serializers.values
end