Class: Sinatra::Rabbit::Collection

Inherits:
BaseCollection show all
Includes:
DSL
Defined in:
lib/sinatra/rabbit/base.rb

Defined Under Namespace

Classes: Operation

Class Method Summary collapse

Methods included from DSL

<<, #[], #collection, #collections, register_collection

Methods inherited from BaseCollection

collection_class, http_method_for, root_path, route_for

Methods inherited from Base

options

Class Method Details

.[](obj_id) ⇒ Object



226
227
228
# File 'lib/sinatra/rabbit/base.rb', line 226

def self.[](obj_id)
  collections.find { |c| c.collection_name == obj_id } || operation(obj_id)
end

.action(action_name, opts = {}, &block) ⇒ Object



272
273
274
275
# File 'lib/sinatra/rabbit/base.rb', line 272

def self.action(action_name, opts={}, &block)
  opts.merge!(:http_method => :post) unless opts[:http_method]
  operation(action_name, opts, &block)
end

.base_classObject



202
203
204
# File 'lib/sinatra/rabbit/base.rb', line 202

def self.base_class
  @klass
end

.base_class=(klass) ⇒ Object



172
173
174
# File 'lib/sinatra/rabbit/base.rb', line 172

def self.base_class=(klass)
  @klass = klass
end

.collection(name, opts = {}, &block) ⇒ Object

Define new collection using the name

opts Define :id used if the collection is a subcollection



151
152
153
154
155
156
157
158
159
160
# File 'lib/sinatra/rabbit/base.rb', line 151

def self.collection(name, opts={}, &block)
  return collections.find { |c| c.collection_name == name } if not block_given?
  new_collection = BaseCollection.collection_class(name, self) do |c|
    c.base_class = self.base_class
    c.with_id!(opts.delete(:with_id)) if opts.has_key?(:with_id)
    c.no_member! if opts.has_key?(:no_member)
    c.generate(name, self, &block)
  end
  collections << new_collection
end

.collection_nameObject



206
# File 'lib/sinatra/rabbit/base.rb', line 206

def self.collection_name; @collection_name; end

.collectionsObject



213
214
215
# File 'lib/sinatra/rabbit/base.rb', line 213

def self.collections
  @collections ||= []
end

.control(*args) ⇒ Object



176
177
178
# File 'lib/sinatra/rabbit/base.rb', line 176

def self.control(*args)
  raise "The 'control' statement must be used only within context of Operation"
end

.description(text = nil) ⇒ Object



221
222
223
224
# File 'lib/sinatra/rabbit/base.rb', line 221

def self.description(text=nil)
  return @description if text.nil?
  @description = text
end

.docs_urlObject



134
135
136
# File 'lib/sinatra/rabbit/base.rb', line 134

def self.docs_url
  root_path  + 'docs/' + route_for(path)
end

.feature(name) ⇒ Object



185
186
187
# File 'lib/sinatra/rabbit/base.rb', line 185

def self.feature(name)
  features.find { |f| f.name == name }
end

.featuresObject



180
181
182
183
# File 'lib/sinatra/rabbit/base.rb', line 180

def self.features
  return [] unless base_class.respond_to? :features
  base_class.features.select { |f| f.collection == collection_name }
end

.features_for(operation_name) ⇒ Object



281
282
283
# File 'lib/sinatra/rabbit/base.rb', line 281

def self.features_for(operation_name)
  features.select { |f| f.operations.map { |o| o.name}.include?(operation_name) }
end

.full_pathObject



217
218
219
# File 'lib/sinatra/rabbit/base.rb', line 217

def self.full_path
  root_path + route_for(path)
end

.generate(name, parent_collection = nil, &block) ⇒ Object



110
111
112
113
114
115
116
117
118
# File 'lib/sinatra/rabbit/base.rb', line 110

def self.generate(name, parent_collection=nil, &block)
  @collection_name = name.to_sym
  @parent_collection = parent_collection
  class_eval(&block)
  generate_head_route unless Rabbit.disabled? :head_routes
  generate_options_route unless Rabbit.disabled? :options_routes
  generate_docs_route unless Rabbit.disabled? :docs
  self
end

.generate_docs_routeObject



138
139
140
141
142
143
144
145
# File 'lib/sinatra/rabbit/base.rb', line 138

def self.generate_docs_route
  collection = self
  base_class.get docs_url do
    css_file = File.read(File.join(File.dirname(__FILE__), '..', 'docs', 'bootstrap.min.css'))
    collection_file = File.read(File.join(File.dirname(__FILE__), '..', 'docs', 'collection.haml'))
    haml collection_file, :locals => { :collection => collection, :css => css_file }
  end
end

.generate_head_routeObject



128
129
130
131
132
# File 'lib/sinatra/rabbit/base.rb', line 128

def self.generate_head_route
  base_class.head full_path do
    status 200
  end
end

.generate_options_routeObject



120
121
122
123
124
125
126
# File 'lib/sinatra/rabbit/base.rb', line 120

def self.generate_options_route
  methods = (['OPTIONS'] + operations.map { |o| o.http_method.to_s.upcase }).uniq.join(',')
  base_class.options full_path do
    headers 'Allow' => methods
    status 200
  end
end

.no_member!Object



193
194
195
# File 'lib/sinatra/rabbit/base.rb', line 193

def self.no_member!
  @no_member = true
end

.operation(operation_name, opts = {}, &block) ⇒ Object



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/sinatra/rabbit/base.rb', line 230

def self.operation(operation_name, opts={}, &block)
  # Return operation when no block is given
  return operations.find { |o| o.operation_name == operation_name } unless block_given?

  # Check if current operation is not already registred
  if operation_registred?(operation_name)
    raise "Operation #{operation_name} already registered in #{self.name} collection"
  end

  # Create operation class
  new_operation = operation_class(self, operation_name).generate(self, operation_name, opts, &block)
  operations << new_operation

  # Add route conditions if defined
  if opts.has_key? :if
    base_class.send(:set, :if_true) do |value|
      condition do
        (value.kind_of?(Proc) ? value.call : value) == true
      end
    end
    opts[:if_true] = opts.delete(:if)
  end

  # Make the full_path method on operation return currect operation path
  new_operation.route = root_path + route_for(path, operation_name, :id_name => @with_id || ':id')

  # Change the HTTP method to POST automatically for 'action' operations
  new_operation.http_method = opts.delete(:http_method) if opts[:http_method]

  # Remove :with_capability from Sinatra route options
  route_options = opts.clone
  route_options.delete :with_capability

  # Define Sinatra route and generate OPTIONS route if enabled
  base_class.send(new_operation.http_method || http_method_for(operation_name), new_operation.full_path, route_options, &new_operation.control)

  new_operation.generate_options_route(root_path + route_for(path, operation_name, :no_id_and_member)) unless Rabbit.disabled?(:options_routes)
  new_operation.generate_head_route(root_path + route_for(path, operation_name, :member)) unless Rabbit.disabled?(:head_routes)
  new_operation.generate_docs_route(new_operation.docs_url) unless Rabbit.disabled?(:doc_routes)
  self
end

.operationsObject



277
278
279
# File 'lib/sinatra/rabbit/base.rb', line 277

def self.operations
  @operations ||= []
end

.parent_collectionObject



207
# File 'lib/sinatra/rabbit/base.rb', line 207

def self.parent_collection; @parent_collection; end

.parent_routesObject



162
163
164
165
166
167
168
169
170
# File 'lib/sinatra/rabbit/base.rb', line 162

def self.parent_routes
  return '' if @parent_collection.nil?
  route = [ @parent_collection.collection_name.to_s ]
  current_parent = @parent_collection
  while current_parent = current_parent.parent_collection
    route << current_parent.collection_name
  end
  route.reverse.join('/')+'/'
end

.pathObject



197
198
199
200
# File 'lib/sinatra/rabbit/base.rb', line 197

def self.path
  with_id_param = @with_id.nil? ? '' : ':id' + (@no_member ? '' : '/')
  parent_routes + with_id_param + ((@no_member) ? '' :  collection_name.to_s)
end

.subcollection?Boolean

Returns:

  • (Boolean)


209
210
211
# File 'lib/sinatra/rabbit/base.rb', line 209

def self.subcollection?
  !parent_collection.nil?
end

.with_id!(id) ⇒ Object



189
190
191
# File 'lib/sinatra/rabbit/base.rb', line 189

def self.with_id!(id)
  @with_id = ":#{id}"
end