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.



116
117
118
119
120
121
122
# File 'lib/sinatra/rabbit.rb', line 116

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.



114
115
116
# File 'lib/sinatra/rabbit.rb', line 114

def name
  @name
end

#operationsObject (readonly)

Returns the value of attribute operations.



114
115
116
# File 'lib/sinatra/rabbit.rb', line 114

def operations
  @operations
end

Instance Method Details

#add_feature_params(features) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/sinatra/rabbit.rb', line 178

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.



127
128
129
130
# File 'lib/sinatra/rabbit.rb', line 127

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

#generateObject



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

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



132
133
134
135
136
137
138
139
140
141
# File 'lib/sinatra/rabbit.rb', line 132

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)



158
159
160
161
# File 'lib/sinatra/rabbit.rb', line 158

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