From c8efa4bffcf0db921fcaff888fca1934626ee2f1 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Fri, 24 Aug 2018 11:26:49 +0200 Subject: [PATCH] Add SHOW, UPDATE and DELETE inventory item endpoints [SCI-2688][SCI-2689] --- .../api/v1/inventories_controller.rb | 7 ++- .../api/v1/inventory_items_controller.rb | 60 ++++++++++++++++++- app/controllers/api/v1/teams_controller.rb | 8 ++- app/models/repository_asset_value.rb | 13 ++++ app/models/repository_cell.rb | 2 +- app/models/repository_date_value.rb | 10 ++++ app/models/repository_list_value.rb | 16 +++++ app/models/repository_text_value.rb | 10 ++++ config/routes.rb | 7 ++- 9 files changed, 121 insertions(+), 12 deletions(-) diff --git a/app/controllers/api/v1/inventories_controller.rb b/app/controllers/api/v1/inventories_controller.rb index e8c8ad6b4..3fa7e17f5 100644 --- a/app/controllers/api/v1/inventories_controller.rb +++ b/app/controllers/api/v1/inventories_controller.rb @@ -7,8 +7,9 @@ module Api before_action :load_inventory, only: %i(show) def index - inventories = - @team.repositories.page(params[:page]).per(params[:page_size]) + inventories = @team.repositories + .page(params.dig(:page, :number)) + .per(params.dig(:page, :size)) render jsonapi: inventories, each_serializer: InventorySerializer end @@ -20,7 +21,7 @@ module Api def load_team @team = Team.find(params.require(:team_id)) - return render jsonapi: {}, status: :forbidden unless can_read_team?(@team) + render jsonapi: {}, status: :forbidden unless can_read_team?(@team) end def load_inventory diff --git a/app/controllers/api/v1/inventory_items_controller.rb b/app/controllers/api/v1/inventory_items_controller.rb index 0971c1d78..d00c7b4a6 100644 --- a/app/controllers/api/v1/inventory_items_controller.rb +++ b/app/controllers/api/v1/inventory_items_controller.rb @@ -5,7 +5,8 @@ module Api class InventoryItemsController < BaseController before_action :load_team before_action :load_inventory - before_action :check_manage_permissions, only: %i(create) + before_action :load_inventory_item, only: %i(show update destroy) + before_action :check_manage_permissions, only: %i(create update destroy) def index items = @@ -35,7 +36,7 @@ module Api cell_attributes = cell_params[:attributes] column = @inventory.repository_columns.find(cell_attributes[:column_id]) - RepositoryCell.create_with_value( + RepositoryCell.create_with_value!( item, column, cell_attributes[:value], current_user ) end @@ -49,17 +50,62 @@ module Api status: :created end + def show + render jsonapi: @inventory_item, + serializer: InventoryItemSerializer, + include: :inventory_cells + end + + def update + item_changed = false + if inventory_cells_params.present? + inventory_cells_params.each do |p| + p.require(%i(id attributes)) + p.require(:attributes).require(:value) + end + @inventory_item.transaction do + inventory_cells_params.each do |cell_params| + cell = @inventory_item.repository_cells.find(cell_params[:id]) + cell_value = cell_params.dig(:attributes, :value) + next unless cell.value.data_changed?(cell_value) + cell.value.update_data!(cell_value, current_user) + item_changed = true + end + end + end + @inventory_item.attributes = update_inventory_item_params + item_changed = true if @inventory_item.changed? + if item_changed + @inventory_item.last_modified_by = current_user + @inventory_item.save! + render json: @inventory_item, + serializer: InventoryItemSerializer, + include: :inventory_cells + else + render body: nil + end + end + + def destroy + @inventory_item.destroy! + render body: nil + end + private def load_team @team = Team.find(params.require(:team_id)) - return render jsonapi: {}, status: :forbidden unless can_read_team?(@team) + render jsonapi: {}, status: :forbidden unless can_read_team?(@team) end def load_inventory @inventory = @team.repositories.find(params.require(:inventory_id)) end + def load_inventory_item + @inventory_item = @inventory.repository_rows.find(params[:id].to_i) + end + def check_manage_permissions unless can_manage_repository_rows?(@team) render body: nil, status: :forbidden @@ -75,6 +121,14 @@ module Api params.permit(data: { attributes: %i(name uid) })[:data] end + def update_inventory_item_params + unless params.require(:data).require(:id).to_i == params[:id].to_i + raise ActionController::BadRequest, + 'Object ID mismatch in URL and request body' + end + inventory_item_params[:attributes] + end + # Partially implement sideposting draft # https://github.com/json-api/json-api/pull/1197 def inventory_cells_params diff --git a/app/controllers/api/v1/teams_controller.rb b/app/controllers/api/v1/teams_controller.rb index 2c8630098..53e6e0c0c 100644 --- a/app/controllers/api/v1/teams_controller.rb +++ b/app/controllers/api/v1/teams_controller.rb @@ -1,10 +1,14 @@ +# frozen_string_literal: true + module Api module V1 class TeamsController < BaseController before_action :load_team, only: :show def index - teams = current_user.teams.page(params[:page]).per(params[:page_size]) + teams = current_user.teams + .page(params.dig(:page, :number)) + .per(params.dig(:page, :size)) render jsonapi: teams, each_serializer: TeamSerializer end @@ -16,7 +20,7 @@ module Api def load_team @team = Team.find(params.require(:id)) - return render jsonapi: {}, status: :forbidden unless can_read_team?(@team) + render jsonapi: {}, status: :forbidden unless can_read_team?(@team) end end end diff --git a/app/models/repository_asset_value.rb b/app/models/repository_asset_value.rb index 7e58168af..a8bb65de2 100644 --- a/app/models/repository_asset_value.rb +++ b/app/models/repository_asset_value.rb @@ -23,6 +23,19 @@ class RepositoryAssetValue < ApplicationRecord asset.file_file_name end + def data_changed?(_new_data) + true + end + + def update_data!(new_data, user) + file = Paperclip.io_adapters.for(new_data[:file_data]) + file.original_filename = new_data[:file_name] + asset.file = file + asset.last_modified_by = user + self.last_modified_by = user + asset.save! && save! + end + def self.new_with_payload(payload, attributes) value = new(attributes) team = value.repository_cell.repository_column.repository.team diff --git a/app/models/repository_cell.rb b/app/models/repository_cell.rb index 3bd9ad3f5..da502e3fa 100644 --- a/app/models/repository_cell.rb +++ b/app/models/repository_cell.rb @@ -41,7 +41,7 @@ class RepositoryCell < ActiveRecord::Base uniqueness: { scope: :repository_column }, unless: :importing - def self.create_with_value(row, column, data, user) + def self.create_with_value!(row, column, data, user) cell = new(repository_row: row, repository_column: column) cell.transaction do value_klass = column.data_type.constantize diff --git a/app/models/repository_date_value.rb b/app/models/repository_date_value.rb index 232d914eb..24c04aaa6 100644 --- a/app/models/repository_date_value.rb +++ b/app/models/repository_date_value.rb @@ -18,6 +18,16 @@ class RepositoryDateValue < ApplicationRecord data end + def data_changed?(new_data) + new_data != data + end + + def update_data!(new_data, user) + self.data = new_data + self.last_modified_by = user + save! + end + def self.new_with_payload(payload, attributes) value = new(attributes) value.data = payload diff --git a/app/models/repository_list_value.rb b/app/models/repository_list_value.rb index 72d61390c..d1488965a 100644 --- a/app/models/repository_list_value.rb +++ b/app/models/repository_list_value.rb @@ -11,6 +11,12 @@ class RepositoryListValue < ApplicationRecord accepts_nested_attributes_for :repository_cell validates :repository_cell, presence: true + validates_inclusion_of :repository_list_item, + in: (lambda do |list_value| + list_value.repository_cell + .repository_column + .repository_list_items + end) def formatted data.to_s @@ -21,6 +27,16 @@ class RepositoryListValue < ApplicationRecord repository_list_item.data end + def data_changed?(new_data) + new_data.to_i != repository_list_item_id + end + + def update_data!(new_data, user) + self.repository_list_item_id = new_data.to_i + self.last_modified_by = user + save! + end + def self.new_with_payload(payload, attributes) value = new(attributes) value.repository_list_item = value.repository_cell diff --git a/app/models/repository_text_value.rb b/app/models/repository_text_value.rb index c3524aad4..d40e8a7bf 100644 --- a/app/models/repository_text_value.rb +++ b/app/models/repository_text_value.rb @@ -19,6 +19,16 @@ class RepositoryTextValue < ApplicationRecord data end + def data_changed?(new_data) + new_data != data + end + + def update_data!(new_data, user) + self.data = new_data + self.last_modified_by = user + save! + end + def self.new_with_payload(payload, attributes) value = new(attributes) value.data = payload diff --git a/config/routes.rb b/config/routes.rb index 0c8dffe3c..4336f7236 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -545,9 +545,10 @@ Rails.application.routes.draw do resources :teams, only: %i(index show) do resources :inventories, only: %i(index show) do get 'columns', to: 'inventory_columns#index' - resources :inventory_items, only: %i(index create), - path: 'items', - as: :items + resources :inventory_items, + only: %i(index create show update destroy), + path: 'items', + as: :items end end resources :users, only: %i(show) do