diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 871ab7d4..ec0b7013 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -132,6 +132,22 @@ private end end + # General handler of json responses. Will be able to set some additional communication data. + # By default a response is ok. + def json_response(obj, options = {}) + if obj.is_a?(SimplyStored::Couch) + if obj.errors.present? + json_api_errors = obj.errors.details.map{|key, ers| {id: key, status: '422', title: ers.map{|e| e[:error].to_s}.join(', '), source: {parameter: key}}} + options.reverse_merge(json: {errors: json_api_errors, ok: false}, status: :unprocessable_entity) + else + options.reverse_merge(json: obj) + end + else # assume crude Hash + obj[:ok] = true unless obj.has_key?(:ok) + obj + end + end + def force_reloads load Rails.root.join('config/initializers/custom_form_builder.rb') end diff --git a/app/controllers/suppliers/products_controller.rb b/app/controllers/suppliers/products_controller.rb index b4df84e5..5f0fe544 100644 --- a/app/controllers/suppliers/products_controller.rb +++ b/app/controllers/suppliers/products_controller.rb @@ -68,10 +68,10 @@ module Suppliers respond_to do |format| if @product.update_attributes(product_params) format.html { redirect_to [:suppliers, :products], notice: t('action.update.successfull', model: Product.model_name.human) } - format.json { render json: @product } + format.json { render json_response @product } else format.html { render action: "edit" } - format.json { render json: {errors: @product.errors}, status: :unprocessable_entity } + format.json { render json_response @product } end end end @@ -96,11 +96,34 @@ module Suppliers def product_params permitted_attributes = [:name, :code, :price, :description, :image, :visible, :position, :active, :product_category_id] # do not raise in development and test for json communication - if request.format.json? + result = if request.format.json? params.require(:product).slice(*permitted_attributes).permit! else params.require(:product).permit permitted_attributes end + decode_base64_params result, :image + end + + BASE64_IMAGE_MATCHER = /^data:image\/(\w+);base64,/ # data:image/png;base64, + # inspired by: https://stackoverflow.com/questions/32984963/upload-base64-encoded-image-with-paperclip-rails + def decode_base64_params(authorized_params, attributes = []) + tempfiles = [] + attributes = Array.wrap(attributes) # allow single attribute argument without array notation + attributes.each do |attribute| + if value = authorized_params[attribute].presence + if value.is_a?(String) and match = value.match(BASE64_IMAGE_MATCHER) + image_type = match[1] + decoded_attribute = Base64.decode64 value.sub BASE64_IMAGE_MATCHER, '' + file = Tempfile.new(['image', ".#{image_type}"]) + file.binmode + file.write decoded_attribute + authorized_params[attribute] = file + end + end + end + authorized_params + ensure + tempfiles.each &:unlink end end end diff --git a/app/controllers/users/application_controller.rb b/app/controllers/users/application_controller.rb index 2f23367a..9e66e818 100644 --- a/app/controllers/users/application_controller.rb +++ b/app/controllers/users/application_controller.rb @@ -30,12 +30,6 @@ module Users flash.now[:notice] = t("messages.#{params[:message]}", list: List.model_name.human, supplier: Supplier.model_name.human) if params[:message].present? && params[:message] =~ /^\w+$/ end - # General handler of json responses. Will be able to set some additional communication data. - # By default a response is ok. - def json_response(obj = {}) - obj[:ok] = true unless obj.has_key?(:ok) - obj - end def new_order_product_orders case params[:product_orders] diff --git a/config/application.rb b/config/application.rb index 8b3c0f32..9d3e81a9 100644 --- a/config/application.rb +++ b/config/application.rb @@ -239,7 +239,7 @@ module Qwaiter config.encoding = "utf-8" # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters += [:password] + config.filter_parameters += [:password, :image] # image will be base64 string from ember (supplier/product) # Enable escaping HTML in JSON. config.active_support.escape_html_entities_in_json = true