diff --git a/app/controllers/api/v1/establishments_controller.rb b/app/controllers/api/v1/establishments_controller.rb new file mode 100644 index 0000000..c93ecc4 --- /dev/null +++ b/app/controllers/api/v1/establishments_controller.rb @@ -0,0 +1,87 @@ +class Api::V1::EstablishmentsController < ApplicationController + before_action :authenticate_user!, only: %i[create update destroy] + before_action :set_doctor_profile, only: %i[create update destroy] + before_action :set_establishment, only: %i[update destroy] + + def index + establishments = filter_establishments + if establishments.exists? + render_success('Establishments found successfully.', establishments) + else + render_error('No establishments match the given criteria.', :not_found) + end + end + + def show + establishment = Establishment.find_by(id: params[:id]) + if establishment + render_success('Establishment found successfully.', establishment) + else + render_error('Establishment not found.', :not_found) + end + end + + def create + establishment = @doctor_profile.establishments.create(establishment_params) + if establishment.persisted? + render_success('Establishment created successfully.', establishment) + else + render_error("Establishment could not be created. #{establishment.errors.full_messages.to_sentence}") + end + end + + def update + if @establishment.update(establishment_params) + render_success('Establishment updated successfully.', @establishment) + else + render_error("Establishment could not be updated. #{@establishment.errors.full_messages.to_sentence}") + end + end + + def destroy + @establishment.destroy + render_success('Establishment deleted successfully.') + end + + private + + def establishment_params + params.require(:establishment).permit(:name, :latitude, :longitude, :maps_location, address_attributes: [:address_line_1, :address_line_2, :city, :state, :country, :pin_code]) + end + + def set_doctor_profile + @doctor_profile = current_user&.doctor_profile + return render_error('User is not authorized.', :forbidden) unless @doctor_profile + end + + def set_establishment + @establishment = @doctor_profile.establishments.find_by(id: params[:id]) + render_error('Establishment not found.', :not_found) unless @establishment + end + + def filter_establishments + filter_params = params.permit(:name, :city, :state, :country, :pin_code, :doctor_profile_id) + + scope = Establishment.all + scope = scope.joins(:address) if address_filter_params_present?(filter_params) + scope = scope.joins(:doctor_profiles) if filter_params[:doctor_profile_id].present? + + scope = scope.where(name: filter_params[:name]) if filter_params[:name].present? + scope = scope.where(addresses: { city: filter_params[:city], state: filter_params[:state], country: filter_params[:country], pin_code: filter_params[:pin_code] }.compact) if address_filter_params_present?(filter_params) + scope = scope.where(doctor_profiles: { id: filter_params[:doctor_profile_id] }) if filter_params[:doctor_profile_id].present? + + scope + end + + def address_filter_params_present?(filter_params) + filter_params[:city].present? || filter_params[:state].present? || filter_params[:country].present? || filter_params[:pin_code].present? + end + + def render_success(message, data = nil) + render json: { message: message, data: data }.compact, status: :ok + end + + def render_error(message, status = :unprocessable_entity) + render json: { message: message }, status: status + end +end diff --git a/app/models/address.rb b/app/models/address.rb index a19addc..4dd4670 100644 --- a/app/models/address.rb +++ b/app/models/address.rb @@ -1,2 +1,3 @@ class Address < ApplicationRecord + validates :address_line_1, :city, :state, :country, :pin_code, presence: true end diff --git a/app/models/doctor_profile.rb b/app/models/doctor_profile.rb index f5f3393..984f30d 100644 --- a/app/models/doctor_profile.rb +++ b/app/models/doctor_profile.rb @@ -3,4 +3,6 @@ class DoctorProfile < ApplicationRecord belongs_to :degree, optional: true belongs_to :institute, optional: true has_one :user -end \ No newline at end of file + has_many :doctor_establishments, dependent: :destroy + has_many :establishments, through: :doctor_establishments +end diff --git a/app/models/establishment.rb b/app/models/establishment.rb index a8fc9a0..43cd501 100644 --- a/app/models/establishment.rb +++ b/app/models/establishment.rb @@ -1,2 +1,9 @@ class Establishment < ApplicationRecord + belongs_to :address + has_many :doctor_establishments, dependent: :destroy + has_many :doctor_profiles, through: :doctor_establishments + + validates :name, presence: true + + accepts_nested_attributes_for :address, update_only: true end diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb index 5f1e042..6bbee6e 100644 --- a/config/initializers/cors.rb +++ b/config/initializers/cors.rb @@ -11,6 +11,7 @@ resource "*", headers: :any, - methods: [:get, :post, :put, :patch, :delete, :options, :head] + methods: [:get, :post, :put, :patch, :delete, :options, :head], + expose: ["Authorization"] end end diff --git a/config/routes.rb b/config/routes.rb index 7703399..580b1dd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,11 @@ registration: 'signup' } # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + namespace :api do + namespace :v1 do + resources :establishments + end + end # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to verify that the app is live.