X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/2a82ddb3105f432d672cb4a359db69506bade948..9f0425e75ee9b29b2567b6717b5ddd5c02e285f1:/app/controllers/application_controller.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index aa6d3b8260..e9d715b653 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,17 +3,49 @@ class ApplicationController < ActionController::Base before_filter :uncamelcase_params_hash_keys before_filter :find_object_by_uuid, :except => :index + unless Rails.application.config.consider_all_requests_local + rescue_from Exception, + :with => :render_error + rescue_from ActiveRecord::RecordNotFound, + :with => :render_not_found + rescue_from ActionController::RoutingError, + :with => :render_not_found + rescue_from ActionController::UnknownController, + :with => :render_not_found + rescue_from ActionController::UnknownAction, + :with => :render_not_found + end + + def render_error(e) + logger.error e.inspect + logger.error e.backtrace.collect { |x| x + "\n" }.join('') if e.backtrace + if @object and @object.errors and @object.errors.full_messages + errors = @object.errors.full_messages + else + errors = [e.inspect] + end + render json: { errors: errors }, status: 422 + end + + def render_not_found(e=ActionController::RoutingError.new("Path not found")) + logger.error e.inspect + render json: { errors: ["Path not found"] }, status: 401 + end + def index @objects ||= model_class.all render_list end def show - render json: @object + render_for_api :superuser, json: @object end def create @attrs = params[resource_name] + if @attrs.nil? + raise "no #{resource_name} (or #{resource_name.camelcase(:lower)}) provided with request #{params.inspect}" + end if @attrs.class == String @attrs = uncamelcase_hash_keys(JSON.parse @attrs) end @@ -22,6 +54,15 @@ class ApplicationController < ActionController::Base show end + def update + @attrs = params[resource_name] + if @attrs.is_a? String + @attrs = uncamelcase_hash_keys(JSON.parse @attrs) + end + @object.update_attributes @attrs + show + end + protected def model_class @@ -29,20 +70,36 @@ class ApplicationController < ActionController::Base end def resource_name # params[] key used by client - controller_name.classify.camelcase(:lower) + controller_name.singularize end def find_object_by_uuid - logger.info params.inspect + if params[:id] and params[:id].match /\D/ + params[:uuid] = params.delete :id + end @object = model_class.where('uuid=?', params[:uuid]).first end + def self.accept_attribute_as_json(attr, force_class=nil) + before_filter lambda { accept_attribute_as_json attr, force_class } + end + def accept_attribute_as_json(attr, force_class) + if params[resource_name].is_a? Hash + if params[resource_name][attr].is_a? String + params[resource_name][attr] = JSON.parse params[resource_name][attr] + if force_class and !params[resource_name][attr].is_a? force_class + raise TypeError.new("#{resource_name}[#{attr.to_s}] must be a #{force_class.to_s}") + end + end + end + end + def uncamelcase_params_hash_keys - uncamelcase_hash_keys(params) + self.params = uncamelcase_hash_keys(params) end - def uncamelcase_hash_keys(h) - if h.is_a? Hash + def uncamelcase_hash_keys(h, max_depth=-1) + if h.is_a? Hash and max_depth != 0 nh = Hash.new h.each do |k,v| if k.class == String @@ -52,7 +109,7 @@ class ApplicationController < ActionController::Base else nk = k end - nh[nk] = uncamelcase_hash_keys(v) + nh[nk] = uncamelcase_hash_keys(v, max_depth-1) end h.replace(nh) end @@ -66,7 +123,7 @@ class ApplicationController < ActionController::Base :self_link => "", :next_page_token => "", :next_link => "", - :items => @objects.map { |x| x } + :items => @objects.as_api_response(:superuser) } render json: @object_list end