Class: Sinatra::Rabbit::Collection

Inherits:
Object
  • Object
show all
Defined in:
lib/sinatra/rabbit.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, &block) ⇒ Collection

Returns a new instance of Collection.



122
123
124
125
126
127
128
# File 'lib/sinatra/rabbit.rb', line 122

def initialize(name, &block)
  @name = name
  @description = ""
  @operations = {}
  instance_eval(&block) if block_given?
  generate_documentation
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



120
121
122
# File 'lib/sinatra/rabbit.rb', line 120

def name
  @name
end

#operationsObject (readonly)

Returns the value of attribute operations.



120
121
122
# File 'lib/sinatra/rabbit.rb', line 120

def operations
  @operations
end

Instance Method Details

#add_feature_params(features) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/sinatra/rabbit.rb', line 184

def add_feature_params(features)
  features.each do |f|
    f.operations.each do |fop|
      if cop = operations[fop.name]
        fop.params.each_key do |k|
          if cop.params.has_key?(k)
            raise DuplicateParamException, "Parameter '#{k}' for operation #{fop.name} defined by collection #{@name} and by feature #{f.name}"
          else
            cop.params[k] = fop.params[k]
          end
        end
      end
    end
  end
end

#description(text = '') ⇒ Object

Set/Return description for collection If first parameter is not present, full description will be returned.



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

def description(text='')
  return @description if text.blank?
  @description = text
end

#generateObject



169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/sinatra/rabbit.rb', line 169

def generate
  operations.values.each { |op| op.generate }
  app = ::Sinatra::Application
  collname = name # Work around Ruby's weird scoping/capture
  app.send(:define_method, "#{name.to_s.singularize}_url") do |id|
      url_for "/api/#{collname}/#{id}", :full
  end

  if index_op = operations[:index]
    app.send(:define_method, "#{name}_url") do
      url_for index_op.path.gsub(/\/\?$/,''), :full
    end
  end
end

#generate_documentationObject



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

def generate_documentation
  coll, oper, features = self, @operations, driver.features(name)
  ::Sinatra::Application.get("/api/docs/#{@name}") do
    @collection, @operations, @features = coll, oper, features
    respond_to do |format|
      format.html { haml :'docs/collection' }
      format.xml { haml :'docs/collection' }
    end
  end
end

#operation(name, opts = {}, &block) ⇒ Object

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)



164
165
166
167
# File 'lib/sinatra/rabbit.rb', line 164

def operation(name, opts = {}, &block)
  raise DuplicateOperationException if @operations[name]
  @operations[name] = Operation.new(self, name, opts, &block)
end