From acc00ff3b9fb72b192aba980b47e1d6f905412b6 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Thu, 13 Sep 2018 10:37:21 +0200 Subject: [PATCH] Add CREATE Result endpoint: Create Text result [SCI-2718] --- app/controllers/api/v1/results_controller.rb | 116 ++++++++++++++++++ .../api/v1/result_asset_serializer.rb | 10 ++ app/serializers/api/v1/result_serializer.rb | 22 ++++ .../api/v1/result_table_serializer.rb | 10 ++ .../api/v1/result_text_serializer.rb | 10 ++ config/routes.rb | 4 +- 6 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 app/controllers/api/v1/results_controller.rb create mode 100644 app/serializers/api/v1/result_asset_serializer.rb create mode 100644 app/serializers/api/v1/result_serializer.rb create mode 100644 app/serializers/api/v1/result_table_serializer.rb create mode 100644 app/serializers/api/v1/result_text_serializer.rb diff --git a/app/controllers/api/v1/results_controller.rb b/app/controllers/api/v1/results_controller.rb new file mode 100644 index 000000000..f37ac241a --- /dev/null +++ b/app/controllers/api/v1/results_controller.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +module Api + module V1 + class ResultsController < BaseController + include TinyMceHelper + + before_action :load_vars + before_action :load_result, only: %i(show update destroy) + before_action :check_manage_permissions, only: %i(create update destroy) + + def index + results = @task.results + .page(params.dig(:page, :number)) + .per(params.dig(:page, :size)) + render jsonapi: results, each_serializer: ResultSerializer, + include: %i(asset table text) + end + + def create + create_text_result if result_text_params.present? + throw ActionController::ParameterMissing unless @result + render jsonapi: @result, + serializer: ResultSerializer, + include: %i(asset table text), + status: :created + end + + def show + render jsonapi: @result, serializer: ResultSerializer, + include: %i(asset table text) + end + + private + + def load_vars + @team = Team.find(params.require(:team_id)) + render jsonapi: {}, status: :forbidden unless can_read_team?(@team) + + @project = @team.projects.find(params.require(:project_id)) + render jsonapi: {}, status: :forbidden unless can_read_project?( + @project + ) + + @experiment = @project.experiments.find(params.require(:experiment_id)) + render jsonapi: {}, status: :forbidden unless can_read_experiment?( + @experiment + ) + + @task = @experiment.my_modules.find(params.require(:task_id)) + end + + def load_result + @result = @task.results.find(params.require(:id)) + end + + def check_manage_permissions + render body: nil, status: :forbidden unless can_manage_module?(@task) + end + + def create_text_result + result_text = ResultText.new( + text: result_text_params.require(:attributes).require(:text) + ) + result_text.transaction do + if tiny_mce_asset_params.present? + tiny_mce_asset_params.each do |t| + image_params = t[:attributes] + token = image_params[:file_token] + unless result_text.text["[~tiny_mce_id:#{token}]"] + raise StandardError, 'Image reference not found in the text' + end + image = Paperclip.io_adapters.for(image_params[:file_data]) + image.original_filename = image_params[:file_name] + tiny_img = TinyMceAsset.create!(image: image, team: @team) + result_text.text.sub!("[~tiny_mce_id:#{token}]", + "[~tiny_mce_id:#{tiny_img.id}]") + end + end + @result = Result.new( + user: current_user, + my_module: @task, + name: result_params[:name], + result_text: result_text, + last_modified_by: current_user + ) + @result.save! && result_text.save! + link_tiny_mce_assets(result_text.text, result_text) + end + end + + def result_params + unless params.require(:data).require(:type) == 'results' + raise ActionController::BadRequest, + 'Wrong object type within parameters' + end + params.require(:data).require(:attributes).require(:name) + params.permit(data: { attributes: :name })[:data] + end + + # Partially implement sideposting draft + # https://github.com/json-api/json-api/pull/1197 + def result_text_params + params[:included]&.select { |el| el[:type] == 'result_texts' }&.first + end + + def tiny_mce_asset_params + prms = params[:included]&.select { |el| el[:type] == 'tiny_mce_assets' } + prms.each do |p| + p.require(:attributes).require(%i(file_data file_name file_token)) + end + prms + end + end + end +end diff --git a/app/serializers/api/v1/result_asset_serializer.rb b/app/serializers/api/v1/result_asset_serializer.rb new file mode 100644 index 000000000..f6638c2b7 --- /dev/null +++ b/app/serializers/api/v1/result_asset_serializer.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Api + module V1 + class ResultAssetSerializer < ActiveModel::Serializer + type :result_assets + attributes :asset_id + end + end +end diff --git a/app/serializers/api/v1/result_serializer.rb b/app/serializers/api/v1/result_serializer.rb new file mode 100644 index 000000000..63733fb80 --- /dev/null +++ b/app/serializers/api/v1/result_serializer.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Api + module V1 + class ResultSerializer < ActiveModel::Serializer + type :results + attributes :name, :archived + has_one :result_asset, key: :asset, + serializer: ResultAssetSerializer, + class_name: 'ResultAsset', + if: -> { object.is_asset } + has_one :result_table, key: :table, + serializer: ResultTableSerializer, + class_name: 'ResultTable', + if: -> { object.is_table } + has_one :result_text, key: :text, + serializer: ResultTextSerializer, + class_name: 'ResultText', + if: -> { object.is_text } + end + end +end diff --git a/app/serializers/api/v1/result_table_serializer.rb b/app/serializers/api/v1/result_table_serializer.rb new file mode 100644 index 000000000..b4bdddc1c --- /dev/null +++ b/app/serializers/api/v1/result_table_serializer.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Api + module V1 + class ResultTableSerializer < ActiveModel::Serializer + type :result_tables + attributes :table_id + end + end +end diff --git a/app/serializers/api/v1/result_text_serializer.rb b/app/serializers/api/v1/result_text_serializer.rb new file mode 100644 index 000000000..a88bdb2f2 --- /dev/null +++ b/app/serializers/api/v1/result_text_serializer.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Api + module V1 + class ResultTextSerializer < ActiveModel::Serializer + type :result_texts + attributes :text + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 5712f8a9a..f2cb62561 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -559,7 +559,9 @@ Rails.application.routes.draw do resources :my_modules, only: %i(index show), path: 'tasks', - as: :tasks + as: :tasks do + resources :results, only: %i(index create show) + end resources :my_module_groups, only: %i(index show), path: 'task_groups',