# File lib/sinatra/rabbit.rb, line 205 def initialize(name, options={}, &block) @name = name @description = "" @operations, @subcollections = {}, {} @global = options[:global] || false instance_eval(&block) if block_given? generate_documentation generate_head generate_options end
# File lib/sinatra/rabbit.rb, line 320 def check_supported(driver) unless global? || driver.has_collection?(@name) || self.kind_of?(Sinatra::Rabbit::SubCollection) raise UnsupportedCollectionException end end
# File lib/sinatra/rabbit.rb, line 297 def collection(name, opts={}, &block) if subcollections.keys.include?(name) raise DuplicateOperationException::new(500, "DuplicateSubcollection", "Subcollection #{name} is already defined", []) end subcollections[name] = SubCollection.new(self, name, opts, &block) subcollections[name].generate end
Set/Return description for collection If first parameter is not present, full description will be returned.
# File lib/sinatra/rabbit.rb, line 223 def description(text='') return @description if text.blank? @description = text end
# File lib/sinatra/rabbit.rb, line 305 def generate operations.values.reject { |op| op.member }.each { |o| o.generate } operations.values.select { |op| op.member }.each { |o| o.generate } app = ::Sinatra::Application collname = name # Work around Ruby's weird scoping/capture app.send(:define_method, "#{name.to_s.singularize}_url") do |id| api_url_for "#{collname}/#{id}", :full end if index_op = operations[:index] app.send(:define_method, "#{name}_url") do api_url_for index_op.path.gsub(/\/\?$/,''), :full end end end
# File lib/sinatra/rabbit.rb, line 260 def generate_documentation coll = self Rabbit::routes << [:get, "#{settings.root_url}/docs/#{@name}"] ::Sinatra::Application.get("#{settings.root_url}/docs/#{@name}") do coll.check_supported(driver) @collection = coll @operations = coll.operations @features = driver.features(coll.name) respond_to do |format| format.html { haml :'docs/collection' } format.xml { haml :'docs/collection' } end end end
# File lib/sinatra/rabbit.rb, line 240 def generate_head current_collection = self Rabbit::routes << [:head, "#{settings.root_url}/#{name}"] ::Sinatra::Application.head("#{settings.root_url}/#{name}") do methods_allowed = current_collection.operations.collect { |o| o[1].method.to_s.upcase }.uniq.join(',') headers 'Allow' => "HEAD,OPTIONS,#{methods_allowed}" [200, ''] end end
# File lib/sinatra/rabbit.rb, line 250 def generate_options current_collection = self Rabbit::routes << [:options, "#{settings.root_url}/#{name}"] ::Sinatra::Application.options("#{settings.root_url}/#{name}") do operations_allowed = current_collection.operations.collect { |o| o[0] }.join(',') headers 'X-Operations-Allowed' => operations_allowed [200, ''] end end
Mark this collection as global, i.e. independent of any specific driver
# File lib/sinatra/rabbit.rb, line 230 def global! @global = true end
Return true if this collection is global, i.e. independent of any specific driver
# File lib/sinatra/rabbit.rb, line 236 def global? @global end
Add a new operation for this collection. For the standard REST operations :index, :show, :update, and :destroy, we already know what method to use and whether this is an operation on the URL for individual elements or for the whole collection.
For non-standard operations, options must be passed:
:method : one of the HTTP methods :member : whether this is an operation on the collection or an individual element (FIXME: custom operations on the collection will use a nonsensical URL) The URL for the operation is the element URL with the name of the operation appended
This also defines a helper method like show_instance_url that returns the URL to this operation (in request context)
# File lib/sinatra/rabbit.rb, line 290 def operation(name, opts = {}, &block) if @operations.keys.include?(name) raise DuplicateOperationException::new(500, "DuplicateOperation", "Operation #{name} is already defined", []) end @operations[name] = Operation.new(self, name, opts, &block) end
Generated with the Darkfish Rdoc Generator 2.