Skip to content

Commit

Permalink
Merge pull request #16 from fmanimashaun/features/models-generation
Browse files Browse the repository at this point in the history
Features/models generation
  • Loading branch information
fmanimashaun authored Feb 15, 2024
2 parents 587dae7 + a043a65 commit 7c9162f
Show file tree
Hide file tree
Showing 59 changed files with 873 additions and 232 deletions.
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ jobs:
RAILS_ENV: test
DATABASE_URL: postgres://postgres:postgres@localhost/test_database
SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE }}
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
run: bundle exec rails db:create db:schema:load && bundle exec rspec
8 changes: 3 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,17 @@ gem 'bootsnap', require: false
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin Ajax possible
gem 'rack-cors'

# Api documentation
gem 'rswag-api'
gem 'rswag-ui'

group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem 'debug', platforms: %i[mri windows]
gem 'factory_bot_rails'
gem 'faker'
gem 'rails-controller-testing'
gem 'rspec-rails'
gem 'rswag'
gem 'rswag-api'
gem 'rswag-specs'
gem 'rswag-ui'
gem 'rubocop', require: false
end

Expand All @@ -58,4 +57,3 @@ end
gem 'devise'
gem 'devise-jwt'
gem 'jsonapi-serializer'
gem 'rswag'
52 changes: 0 additions & 52 deletions app/controllers/api/v1/cities_controller.rb

This file was deleted.

8 changes: 8 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
class ApplicationController < ActionController::API
before_action :configure_permitted_parameters, if: :devise_controller?

protected

def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: %i[name username email])
devise_parameter_sanitizer.permit(:account_update, keys: %i[name username email])
end
end
17 changes: 17 additions & 0 deletions app/controllers/concerns/rack_session_fix.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module RackSessionFix
extend ActiveSupport::Concern
class FakeRackSession < Hash
def enabled?
false
end
end
included do
before_action :set_fake_rack_session_for_devise

private

def set_fake_rack_session_for_devise
request.env['rack.session'] ||= FakeRackSession.new
end
end
end
6 changes: 6 additions & 0 deletions app/controllers/users/current_user_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Users::CurrentUserController < ApplicationController
before_action :authenticate_user!
def index
render json: UserSerializer.new(current_user).serializable_hash[:data][:attributes], status: :ok
end
end
39 changes: 39 additions & 0 deletions app/controllers/users/registrations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class Users::RegistrationsController < Devise::RegistrationsController
include RackSessionFix
respond_to :json

private

def respond_with(resource, _opts = {})
if request.method == 'POST' && resource.persisted?
render json: {
status: {
code: 200,
message: 'Signed up sucessfully.'
},
data:
UserSerializer.new(resource).serializable_hash[:data][
:attributes
]
},
status: :ok
elsif request.method == 'DELETE'
render json: {
status: {
code: 200,
message: 'Account deleted successfully.'
}
},
status: :ok
else
render json: {
status: {
code: 422,
message:
"User couldn't be created successfully. #{resource.errors.full_messages.to_sentence}"
}
},
status: :unprocessable_entity
end
end
end
27 changes: 27 additions & 0 deletions app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class Users::SessionsController < Devise::SessionsController
include RackSessionFix
respond_to :json

private

def respond_with(resource, _opts = {})
render json: {
status: { code: 200, message: 'Logged in sucessfully.' },
data: UserSerializer.new(resource).serializable_hash[:data][:attributes]
}, status: :ok
end

def respond_to_on_destroy
if current_user
render json: {
status: 200,
message: 'logged out successfully'
}, status: :ok
else
render json: {
status: 401,
message: "Couldn't find an active session."
}, status: :unauthorized
end
end
end
2 changes: 2 additions & 0 deletions app/models/car.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Car < ApplicationRecord
end
4 changes: 4 additions & 0 deletions app/models/car_detail.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class CarDetail < ApplicationRecord
belongs_to :car
belongs_to :engine_type
end
1 change: 0 additions & 1 deletion app/models/city.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
class City < ApplicationRecord
validates :name, presence: true
end
2 changes: 2 additions & 0 deletions app/models/engine_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class EngineType < ApplicationRecord
end
5 changes: 5 additions & 0 deletions app/models/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Reservation < ApplicationRecord
belongs_to :city
belongs_to :car
belongs_to :user
end
36 changes: 36 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class User < ApplicationRecord
include Devise::JWT::RevocationStrategies::JTIMatcher

devise :database_authenticatable, :registerable, :recoverable, :validatable, :jwt_authenticatable,
jwt_revocation_strategy: self

has_many :reservations

enum role: { user: 0, admin: 1 }

after_initialize :set_default_role, if: :new_record?

# constants for validation
PASSWORD_INVALID_MESSAGE = 'must include at least one lowercase letter, one uppercase letter, and one digit'.freeze
USERNAME_INVALID_MESSAGE = 'only allows alphanumeric characters and underscores'.freeze
USERNAME_REGEX = /\A[a-zA-Z0-9_.]+\z/
PASSWORD_REGEX = /\A(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}\z/

validates :username, presence: true, uniqueness: true
validates :name, presence: true
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :username, format: { with: USERNAME_REGEX, message: USERNAME_INVALID_MESSAGE }
validates :password, length: { minimum: 8 }, format: { with: PASSWORD_REGEX, message: PASSWORD_INVALID_MESSAGE }

roles.keys.each do |role_name|
define_method("#{role_name}?") do
role == role_name
end
end

private

def set_default_role
self.role ||= :user
end
end
5 changes: 5 additions & 0 deletions app/serializers/car_detail_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class CarDetailSerializer
include JSONAPI::Serializer
attributes :horsepower, :torque, :fuel_economy, :seating_capacity, :cargo_space, :infotainment_system,
:safety_rating, :tech_features, :special_features
end
4 changes: 4 additions & 0 deletions app/serializers/car_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class CarSerializer
include JSONAPI::Serializer
attributes :name, :description
end
4 changes: 4 additions & 0 deletions app/serializers/city_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class CitySerializer
include JSONAPI::Serializer
attributes :name
end
4 changes: 4 additions & 0 deletions app/serializers/engine_type_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class EngineTypeSerializer
include JSONAPI::Serializer
attributes :name
end
4 changes: 4 additions & 0 deletions app/serializers/reservation_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class ReservationSerializer
include JSONAPI::Serializer
attributes :date
end
8 changes: 8 additions & 0 deletions app/serializers/user_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class UserSerializer
include JSONAPI::Serializer
attributes :id, :email, :username, :name, :role

attribute :created_date do |user|
user.created_at&.strftime('%m/%d/%Y')
end
end
2 changes: 1 addition & 1 deletion config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module BookABikeApi
module RailsJwtTutorial
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 7.1
Expand Down
2 changes: 1 addition & 1 deletion config/cable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ test:
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: book_a_bike_api_production
channel_prefix: rails_jwt_tutorial_production
2 changes: 1 addition & 1 deletion config/credentials.yml.enc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
P0XtMJLb09AL5rF2nRhXmeIQvSw6Lpc5cLwk9LKqKpZZmDb0en1Rzb1diXsAHCB5l/K9G+hEepPcVeCqRgoZbdD+i2FB3yleO0hMCBYC9KGC69iPzh/joBNOuWrKbEDTGZi8Ma2BO7W8aii+OmkhPhBxxNXwaHdhZAdQko+jcvn/1FlEkeeZ+7TNpwtXL95aDdTsgm9IQu1m7EJ9zPfmyp9LF6sEp09eqhqBIwsc+Lg6B/EutyQKhwZVoiR6gRa3xKH68sHZWdGDRrS2iagwF4aoJikY6MsRI47YegZ8B0QmDoiMJqrJ9O7w7acCV6nR5tjmf8AB7oyMWw9WvbFAZnR0zrrV0tc1kqc4NoHqerp6SyB0A1FS6okk2C5nAXLpo+5UaAKoNkrVyQOxH09Z+PNxNR/C--cELd5wJ9HCqSGcYl--JH/7Osq4NkZaK6+UyN8Sxw==
HplnKCaSqUE0Mzc9OgrBtnQRXmkt1XzNzilIg60jli7oHQ9MuMiZC0pO0cYla85p7dL5bGGJ5uOkx4s2h2MpOjaDaNiqJor4wxd0Qz9GGmrHXlaUbsLvtfaDDHYxooXm8qQoF7BkW3d036n6v8S+MWTznFOQwthXvwVFJkW2mOcGiSG3IDeFSNrI8/mt2zQ0NCJ1ykOuANB+JLhhFeVwaquxjA0PhJwUpuOm25xs+wxp5bDLjZJyG56w203kRCumrgqgIdCZV7Y7/xSW3O6L0kIoLseTC6jpORu8v7d0zIkgOvJwEdC8513JpVhNknB58W8J7gnDlwrlt6tO+JojC0RDEiiGR3DC7TeW1dZUiLTTHIPR8kUd2vny3hR14t45xe40+iK11bCEPVefj9azkbGXp2Ghlv2xjdn3giiRP3Ec5spFyrMNqZyNi8lDAwpV4Xo1mmcoSbGnGBMdwes3k2vaTa7Mvq758piDm3LWYS51llYlxMdihzMK2pRP4qdwy9cWjTPjgrnFxUk6RPcdmmVEhf4pqmUMCb0jEaXnPIcI2g==--Y0jwt/38HBhybFAB--Uxjp7y0/24KQ6NMGLGuLMA==
12 changes: 6 additions & 6 deletions config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ default: &default

development:
<<: *default
database: book_a_bike_api_development
database: rails_jwt_tutorial_development

# The specified database role being used to connect to PostgreSQL.
# To create additional roles in PostgreSQL see `$ createuser --help`.
# When left blank, PostgreSQL will use the default role. This is
# the same name as the operating system user running Rails.
#username: book_a_bike_api
#username: rails_jwt_tutorial

# The password associated with the PostgreSQL role (username).
#password:
Expand Down Expand Up @@ -55,7 +55,7 @@ development:
# Do not set this db to the same as development or production.
test:
<<: *default
database: book_a_bike_api_test
database: rails_jwt_tutorial_test

# As with config/credentials.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
Expand All @@ -79,6 +79,6 @@ test:
#
production:
<<: *default
database: book_a_bike_api_production
username: book_a_bike_api
password: <%= ENV["BOOK_A_BIKE_API_DATABASE_PASSWORD"] %>
database: rails_jwt_tutorial_production
username: rails_jwt_tutorial
password: <%= ENV["RAILS_JWT_TUTORIAL_DATABASE_PASSWORD"] %>
1 change: 1 addition & 0 deletions config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,5 @@

# Raise error when a before_action's only/except options reference missing actions
config.action_controller.raise_on_missing_callback_actions = true
config.action_mailer.default_url_options = { host: 'localhost', port: 4000 }
end
2 changes: 1 addition & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@

# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "book_a_bike_api_production"
# config.active_job.queue_name_prefix = "rails_jwt_tutorial_production"

config.action_mailer.perform_caching = false

Expand Down
11 changes: 5 additions & 6 deletions config/initializers/cors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@

Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins "*"

resource "*",
headers: :any,
expose: ['access-token', 'expiry', 'token-type',"Authorization"],
methods: [:get, :post, :put, :patch, :delete, :options, :head]
origins '*'
resource '*',
headers: :any,
methods: %i[get post put patch delete options head],
expose: [:Authorization]
end
end
Loading

0 comments on commit 7c9162f

Please sign in to comment.