require 'travis/api/app' class Travis::Api::App class SettingsEndpoint < Endpoint set(:prefix) { "/settings/" << name[/[^:]+$/].underscore } class << self # This method checks if class based on a given name exists or creates # a new SettingsEndpoint subclass, which will be then used as an endpoint def subclass(name) class_name = name.to_s.camelize if Travis::Api::App::Endpoint.const_defined?(class_name) Travis::Api::App::Endpoint.const_get(class_name) else klass = create_settings_class(name) Travis::Api::App::Endpoint.const_set(class_name, klass) klass end end def create_settings_class(name) klass = Class.new(self) do define_method(:name) { name } get("/", scope: :private) do index end get("/:id", scope: :private) do show end post("/", scope: :private) do create end patch("/:id", scope: :private) do update end delete("/:id", scope: :private) do destroy end end end end # Rails style methods for easy overriding def index respond_with(collection, type: name, version: :v2) end def show respond_with(record, type: singular_name, version: :v2) end def update record.update(JSON.parse(request.body.read)[singular_name]) if record.valid? repo_settings.save respond_with(record, type: singular_name, version: :v2) else status 422 respond_with(record, type: :validation_error, version: :v2) end end def create record = collection.create(JSON.parse(request.body.read)[singular_name]) if record.valid? repo_settings.save respond_with(record, type: singular_name, version: :v2) else status 422 respond_with(record, type: :validation_error, version: :v2) end end def destroy record = collection.destroy(params[:id]) || record_not_found repo_settings.save respond_with(record, type: singular_name, version: :v2) end def singular_name name.to_s.singularize end def collection @collection ||= repo_settings.send(name) end # This method can't be called "settings" because it clashes with # Sinatra's method def repo_settings @settings ||= begin service(:find_repo_settings, id: params['repository_id'].to_i).run end || halt(404, error: "Couldn't find repository") end def record collection.find(params[:id]) || record_not_found end def record_not_found halt(404, { error: "Could not find a requested setting" }) end end end