From 859eadada8f7e100ffd64fba6fb9446d56adc45b Mon Sep 17 00:00:00 2001 From: Abdoul Date: Wed, 1 Nov 2023 08:44:59 +0000 Subject: [PATCH 1/3] solvilg n+1 query --- app/controllers/api/v1/cars_controller.rb | 2 +- app/controllers/api/v1/reservations_controller.rb | 10 +++++++++- app/controllers/api/v1/users_controller.rb | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/cars_controller.rb b/app/controllers/api/v1/cars_controller.rb index 2c21d67..400e963 100644 --- a/app/controllers/api/v1/cars_controller.rb +++ b/app/controllers/api/v1/cars_controller.rb @@ -3,7 +3,7 @@ class Api::V1::CarsController < ApplicationController before_action :authenticate, only: %i[index show create destroy] def index - @cars = Car.all + @cars = Car.includes(:user, :reservations).all render json: @cars end diff --git a/app/controllers/api/v1/reservations_controller.rb b/app/controllers/api/v1/reservations_controller.rb index 661f993..439f091 100644 --- a/app/controllers/api/v1/reservations_controller.rb +++ b/app/controllers/api/v1/reservations_controller.rb @@ -4,7 +4,7 @@ class Api::V1::ReservationsController < ApplicationController def index current_user = User.find(params[:user_id]) - @reservations = current_user.reservations.order(created_at: :desc).all + @reservations = current_user.reservations.includes(:user, :reservation).order(created_at: :desc).all if @reservations render json: { status: { code: 200, message: 'Reservations retrieved successfully.', data: @reservations } }, status: :ok else @@ -26,6 +26,14 @@ def create end end + def update + if @reservation.update(reservation_params) + render json: @reservation, status: :ok + else + render json: @reservation.errors, status: :uprocessable_entity + end + end + def destroy @reservation.destroy head :no_content diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index d721541..d6890b2 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -3,7 +3,7 @@ class Api::V1::UsersController < ApplicationController before_action :set_user, only: %i[show update destroy] def index - @users = User.all + @users = User.includes(:cars, :reservations).all if @users render json: { status: { code: 200, message: 'signed in successfuly', data: @users } }, status: :ok From cecf81c2f85298dd1a2c6f003368d5861a3381d1 Mon Sep 17 00:00:00 2001 From: Abdoul Date: Wed, 1 Nov 2023 09:40:07 +0000 Subject: [PATCH 2/3] adding reservation api-docs --- .../api/v1/reservations_controller.rb | 2 +- spec/integration/api/v1/reservations_spec.rb | 142 ++++++++++++++++++ spec/swagger_helper.rb | 2 +- swagger/v1/swagger.yaml | 126 +++++++++++++++- 4 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 spec/integration/api/v1/reservations_spec.rb diff --git a/app/controllers/api/v1/reservations_controller.rb b/app/controllers/api/v1/reservations_controller.rb index 439f091..80624c8 100644 --- a/app/controllers/api/v1/reservations_controller.rb +++ b/app/controllers/api/v1/reservations_controller.rb @@ -4,7 +4,7 @@ class Api::V1::ReservationsController < ApplicationController def index current_user = User.find(params[:user_id]) - @reservations = current_user.reservations.includes(:user, :reservation).order(created_at: :desc).all + @reservations = current_user.reservations.includes(:user, :car).order(created_at: :desc).all if @reservations render json: { status: { code: 200, message: 'Reservations retrieved successfully.', data: @reservations } }, status: :ok else diff --git a/spec/integration/api/v1/reservations_spec.rb b/spec/integration/api/v1/reservations_spec.rb new file mode 100644 index 0000000..ca8c1be --- /dev/null +++ b/spec/integration/api/v1/reservations_spec.rb @@ -0,0 +1,142 @@ +require 'swagger_helper' + +describe 'Reservations API' do + path '/api/v1/users/{user_id}/reservations' do + get 'Retrieves a list of reservations for a user' do + tags 'Reservations' + produces 'application/json' + parameter name: :user_id, in: :path, type: :string + + response '200', 'reservations found' do + run_test! + end + + response '404', 'user not found' do + let(:user_id) { 'invalid_user_id' } + run_test! + end + end + + post 'Creates a new reservation for a user' do + tags 'Reservations' + consumes 'application/json' + parameter name: :user_id, in: :path, type: :string + parameter name: :reservation, in: :body, schema: { + type: :object, + properties: { + location: { type: :string }, + date: { type: :string, format: 'date' }, + car_id: { type: :string } + }, + required: %w[location date car_id] + } + + response '201', 'reservation created' do + let(:user_id) { create(:user).id } + let(:reservation) { { location: 'Sample Location', date: '2023-12-31', car_id: create(:car).id } } + run_test! + end + + response '404', 'user not found' do + let(:user_id) { 'invalid_user_id' } + let(:reservation) { { location: 'Sample Location', date: '2023-12-31', car_id: create(:car).id } } + run_test! + end + + response '422', 'invalid request' do + let(:user_id) { create(:user).id } + let(:reservation) { { location: '', date: '2023-12-31', car_id: create(:car).id } } + run_test! + end + end + end + + path '/api/v1/users/{user_id}/reservations/{id}' do + get 'Retrieves a reservation for a user' do + tags 'Reservations' + produces 'application/json' + parameter name: :user_id, in: :path, type: :string + parameter name: :id, in: :path, type: :string + + response '200', 'reservation found' do + let(:user_id) { create(:user).id } + let(:id) { create(:reservation, user: User.find(user_id)).id } + run_test! + end + + response '404', 'user not found' do + let(:user_id) { 'invalid_user_id' } + let(:id) { create(:reservation).id } + run_test! + end + + response '404', 'reservation not found' do + let(:user_id) { create(:user).id } + let(:id) { 'invalid_id' } + run_test! + end + end + + path '/api/v1/users/{user_id}/reservations/{id}' do + put 'Update the reservations of each cars added' do + tags 'Reservation' + consumes 'apllication/json' + parameter name: :user_id, in: :path, type: :string, required: true + parameter name: :id, in: :path, type: :string, required: true + parameter name: :reservation, in: :body, schema: { + type: :object, + properties: { + location: { type: :string }, + date: { type: :string, format: 'date' }, + car_id: { type: :string } + } + } + response '200', 'update successful' do + end + response '404', 'User not found' do + let(:user_id) { 'nil' } + let(:id) { create(:reservation, user: User.find(:user_id).id) } + let(:reservation) { { location: 'New location', date: '2023-11-01', car_id: create(:car).id } } + run_test! + end + response '404', 'Reservation not found' do + let(:user_id) { create(:user).id } + let(:id) { 'nil id' } + let(:reservation) { { location: 'City', date: '2023-11-02', car_id: create(:car).id } } + run_test! + end + response '422', 'Invalid Request' do + let(:user_id) { create(:user).id } + let(:id) { create(:reservation, user: User.find(:user_id).id) } + let(:reservation) { { location: ' ', date: '2023-11-03', car_id: create(:car).id } } + run_test! + end + end + + delete 'Delete an existing reservation for a user' do + tags 'Reservations' + consumes 'application/json' + parameter name: :user_id, in: :path, type: :string, required: true + parameter name: :id, in: :path, type: :string, required: true + + response '204', 'reservation deleted' do + let(:user_id) { create(:user).id } + let(:id) { create(:reservation, user: User.find(:user_id).id) } + run_test! + end + + response '404', 'reservation not found' do + let(:user_id) { 'invalid user_id' } + let(:id) { create(:reservation).id } + run_test! + end + + response '404', 'reservation not found' do + let(:user_id) { create(:user).id } + let(:id) { 'invalid id' } + run_test! + end + end + end + end +end diff --git a/spec/swagger_helper.rb b/spec/swagger_helper.rb index feaae2b..58efe6d 100644 --- a/spec/swagger_helper.rb +++ b/spec/swagger_helper.rb @@ -22,7 +22,7 @@ paths: {}, servers: [ { - url: 'https://{defaultHost}', + url: 'http://localhost:3000}', variables: { defaultHost: { default: 'www.example.com' diff --git a/swagger/v1/swagger.yaml b/swagger/v1/swagger.yaml index 8c17fee..a143a0c 100644 --- a/swagger/v1/swagger.yaml +++ b/swagger/v1/swagger.yaml @@ -148,6 +148,130 @@ paths: description: car deleted '404': description: car not found + "/api/v1/users/{user_id}/reservations": + get: + summary: Retrieves a list of reservations for a user + tags: + - Reservations + parameters: + - name: user_id + in: path + required: true + schema: + type: string + responses: + '200': + description: reservations found + '404': + description: user not found + post: + summary: Creates a new reservation for a user + tags: + - Reservations + parameters: + - name: user_id + in: path + required: true + schema: + type: string + responses: + '201': + description: reservation created + '404': + description: user not found + '422': + description: invalid request + requestBody: + content: + application/json: + schema: + type: object + properties: + location: + type: string + date: + type: string + format: date + car_id: + type: string + required: + - location + - date + - car_id + "/api/v1/users/{user_id}/reservations/{id}": + get: + summary: Retrieves a reservation for a user + tags: + - Reservations + parameters: + - name: user_id + in: path + required: true + schema: + type: string + - name: id + in: path + required: true + schema: + type: string + responses: + '200': + description: reservation found + '404': + description: reservation not found + put: + summary: Update the reservations of each cars added + tags: + - Reservation + parameters: + - name: user_id + in: path + required: true + schema: + type: string + - name: id + in: path + required: true + schema: + type: string + responses: + '404': + description: Reservation not found + '422': + description: Invalid Request + requestBody: + content: + apllication/json: + schema: + type: object + properties: + location: + type: string + date: + type: string + format: date + car_id: + type: string + delete: + summary: Delete an existing reservation for a user + tags: + - Reservations + parameters: + - name: user_id + in: path + required: true + schema: + type: string + - name: id + in: path + required: true + schema: + type: string + responses: + '204': + description: reservation deleted + '404': + description: reservation not found "/api/v1/users": get: summary: Retrieves a list of users @@ -217,7 +341,7 @@ paths: '404': description: user not found servers: -- url: https://{defaultHost} +- url: http://localhost:3000} variables: defaultHost: default: www.example.com From f4257f1d736da3f072c996e4a224427d9bdb4c32 Mon Sep 17 00:00:00 2001 From: Abdoul Date: Wed, 1 Nov 2023 09:44:32 +0000 Subject: [PATCH 3/3] fixing linters issue --- spec/integration/api/v1/reservations_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/integration/api/v1/reservations_spec.rb b/spec/integration/api/v1/reservations_spec.rb index ca8c1be..f5475f7 100644 --- a/spec/integration/api/v1/reservations_spec.rb +++ b/spec/integration/api/v1/reservations_spec.rb @@ -91,7 +91,11 @@ car_id: { type: :string } } } - response '200', 'update successful' do + response '200', 'Update successful' do + let(:user_id) { create(:user).id } + let(:id) { create(:reservation, user: User.find(:user_id).id) } + let(:reservation) { { location: 'New location', date: '2023-11-01', car_id: create(:car).id } } + run_test! end response '404', 'User not found' do let(:user_id) { 'nil' }