From 80c3d4fb7e2a362dfee8bc7e300b36685da2f29a Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:11:55 -0300 Subject: [PATCH 01/90] Add the tables and models for the ap p --- .../20231025213602_devise_create_users.rb | 44 ++++++++++++++ db/migrate/20231025215248_create_cars.rb | 16 ++++++ .../20231025215755_create_reservations.rb | 14 +++++ db/schema.rb | 57 +++++++++++++++++++ db/seeds.rb | 9 +++ 5 files changed, 140 insertions(+) create mode 100644 db/migrate/20231025213602_devise_create_users.rb create mode 100644 db/migrate/20231025215248_create_cars.rb create mode 100644 db/migrate/20231025215755_create_reservations.rb create mode 100644 db/schema.rb create mode 100644 db/seeds.rb diff --git a/db/migrate/20231025213602_devise_create_users.rb b/db/migrate/20231025213602_devise_create_users.rb new file mode 100644 index 0000000..b99f25b --- /dev/null +++ b/db/migrate/20231025213602_devise_create_users.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +class DeviseCreateUsers < ActiveRecord::Migration[7.1] + def change + create_table :users do |t| + ## Database authenticatable + t.string :email, null: false, default: "" + t.string :encrypted_password, null: false, default: "" + + ## Recoverable + t.string :reset_password_token + t.datetime :reset_password_sent_at + + ## Rememberable + t.datetime :remember_created_at + + ## Trackable + # t.integer :sign_in_count, default: 0, null: false + # t.datetime :current_sign_in_at + # t.datetime :last_sign_in_at + # t.string :current_sign_in_ip + # t.string :last_sign_in_ip + + ## Confirmable + # t.string :confirmation_token + # t.datetime :confirmed_at + # t.datetime :confirmation_sent_at + # t.string :unconfirmed_email # Only if using reconfirmable + + ## Lockable + # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts + # t.string :unlock_token # Only if unlock strategy is :email or :both + # t.datetime :locked_at + + + t.timestamps null: false + end + + add_index :users, :email, unique: true + add_index :users, :reset_password_token, unique: true + # add_index :users, :confirmation_token, unique: true + # add_index :users, :unlock_token, unique: true + end +end diff --git a/db/migrate/20231025215248_create_cars.rb b/db/migrate/20231025215248_create_cars.rb new file mode 100644 index 0000000..f9a0083 --- /dev/null +++ b/db/migrate/20231025215248_create_cars.rb @@ -0,0 +1,16 @@ +class CreateCars < ActiveRecord::Migration[7.1] + def change + create_table :cars do |t| + t.string :name + t.text :description + t.integer :deposit + t.integer :finance_fee + t.integer :option_to_purchase_fee + t.integer :total_amount_payable + t.integer :duration + t.boolean :removed + + t.timestamps + end + end +end diff --git a/db/migrate/20231025215755_create_reservations.rb b/db/migrate/20231025215755_create_reservations.rb new file mode 100644 index 0000000..fcc89ec --- /dev/null +++ b/db/migrate/20231025215755_create_reservations.rb @@ -0,0 +1,14 @@ +class CreateReservations < ActiveRecord::Migration[7.1] + def change + create_table :reservations do |t| + t.references :user, null: false, foreign_key: true + t.references :car, null: false, foreign_key: true + t.datetime :start_time + t.datetime :end_time + t.boolean :available + t.string :city + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..e1fd636 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,57 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema[7.1].define(version: 2023_10_25_215755) do + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "cars", force: :cascade do |t| + t.string "name" + t.text "description" + t.integer "deposit" + t.integer "finance_fee" + t.integer "option_to_purchase_fee" + t.integer "total_amount_payable" + t.integer "duration" + t.boolean "removed" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "reservations", force: :cascade do |t| + t.bigint "user_id", null: false + t.bigint "car_id", null: false + t.datetime "start_time" + t.datetime "end_time" + t.boolean "available" + t.string "city" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["car_id"], name: "index_reservations_on_car_id" + t.index ["user_id"], name: "index_reservations_on_user_id" + end + + create_table "users", force: :cascade do |t| + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false + t.string "reset_password_token" + t.datetime "reset_password_sent_at" + t.datetime "remember_created_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["email"], name: "index_users_on_email", unique: true + t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true + end + + add_foreign_key "reservations", "cars" + add_foreign_key "reservations", "users" +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..4fbd6ed --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,9 @@ +# This file should ensure the existence of records required to run the application in every environment (production, +# development, test). The code here should be idempotent so that it can be executed at any point in every environment. +# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). +# +# Example: +# +# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| +# MovieGenre.find_or_create_by!(name: genre_name) +# end From 54c2525ef6af7eddaa449cda4cd0ce1153967342 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:12:53 -0300 Subject: [PATCH 02/90] Add the rubocop linter --- .rubocop.yml | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..07baeb4 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,60 @@ +AllCops: + NewCops: enable + Exclude: + - "db/**/*" + - "bin/*" + - "config/**/*" + - "Guardfile" + - "Rakefile" + - "node_modules/**/*" + + DisplayCopNames: true + +Layout/LineLength: + Max: 120 +Metrics/MethodLength: + Include: + - "app/controllers/*" + - "app/models/*" + Max: 20 +Metrics/AbcSize: + Include: + - "app/controllers/*" + - "app/models/*" + Max: 50 +Metrics/ClassLength: + Max: 150 +Metrics/BlockLength: + AllowedMethods: ['describe'] + Max: 30 + +Style/Documentation: + Enabled: false +Style/ClassAndModuleChildren: + Enabled: false +Style/EachForSimpleLoop: + Enabled: false +Style/AndOr: + Enabled: false +Style/DefWithParentheses: + Enabled: false +Style/FrozenStringLiteralComment: + EnforcedStyle: never + +Layout/HashAlignment: + EnforcedColonStyle: key +Layout/ExtraSpacing: + AllowForAlignment: false +Layout/MultilineMethodCallIndentation: + Enabled: true + EnforcedStyle: indented +Lint/RaiseException: + Enabled: false +Lint/StructNewOverride: + Enabled: false +Style/HashEachMethods: + Enabled: false +Style/HashTransformKeys: + Enabled: false +Style/HashTransformValues: + Enabled: false \ No newline at end of file From 984a97fcbdb316a4d6f7f69180ef503841bcacee Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:13:23 -0300 Subject: [PATCH 03/90] Add the linters workflow --- .github/workflows/linters.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/linters.yml diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml new file mode 100644 index 0000000..560212b --- /dev/null +++ b/.github/workflows/linters.yml @@ -0,0 +1,30 @@ +name: Linters + +on: pull_request + +env: + FORCE_COLOR: 1 + +jobs: + rubocop: + name: Rubocop + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-ruby@v1 + with: + ruby-version: 3.1.x + - name: Setup Rubocop + run: | + gem install --no-document rubocop -v '>= 1.0, < 2.0' # https://docs.rubocop.org/en/stable/installation/ + [ -f .rubocop.yml ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/ror/.rubocop.yml + - name: Rubocop Report + run: rubocop --color + nodechecker: + name: node_modules checker + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Check node_modules existence + run: | + if [ -d "node_modules/" ]; then echo -e "\e[1;31mThe node_modules/ folder was pushed to the repo. Please remove it from the GitHub repository and try again."; echo -e "\e[1;32mYou can set up a .gitignore file with this folder included on it to prevent this from happening in the future." && exit 1; fi \ No newline at end of file From fb936fdf40cc73b9bd569048ed55b5d68b516a18 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:14:38 -0300 Subject: [PATCH 04/90] Add the rubocop gem, rack cors ande devise --- Gemfile | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Gemfile diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..2a4e6d1 --- /dev/null +++ b/Gemfile @@ -0,0 +1,55 @@ +source "https://rubygems.org" + +ruby "3.2.2" + +# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem "rails", "~> 7.1.1" + +gem 'rubocop', '>= 1.0', '< 2.0' + +gem 'rack-cors' + +gem 'devise' + + +# Use postgresql as the database for Active Record +gem "pg", "~> 1.1" + +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", ">= 5.0" + +# Build JSON APIs with ease [https://github.com/rails/jbuilder] +# gem "jbuilder" + +# Use Redis adapter to run Action Cable in production +# gem "redis", ">= 4.0.1" + +# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] +# gem "kredis" + +# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] +# gem "bcrypt", "~> 3.1.7" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: %i[ windows jruby ] + +# Reduces boot times through caching; required in config/boot.rb +gem "bootsnap", require: false + +# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] +# gem "image_processing", "~> 1.2" + +# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin Ajax possible +# gem "rack-cors" + +group :development, :test do + # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem + gem "debug", platforms: %i[ mri windows ] +end + +group :development do + # Speed up commands on slow machines / big apps [https://github.com/rails/spring] + # gem "spring" + +end + From 4f548dc31038d52fd11a8b7c86fa94dd3cfd4a6a Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:15:42 -0300 Subject: [PATCH 05/90] Upload the gemfile lock with the new gems installed --- Gemfile.lock | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..2a3f279 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,247 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (7.1.1) + actionpack (= 7.1.1) + activesupport (= 7.1.1) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (7.1.1) + actionpack (= 7.1.1) + activejob (= 7.1.1) + activerecord (= 7.1.1) + activestorage (= 7.1.1) + activesupport (= 7.1.1) + mail (>= 2.7.1) + net-imap + net-pop + net-smtp + actionmailer (7.1.1) + actionpack (= 7.1.1) + actionview (= 7.1.1) + activejob (= 7.1.1) + activesupport (= 7.1.1) + mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp + rails-dom-testing (~> 2.2) + actionpack (7.1.1) + actionview (= 7.1.1) + activesupport (= 7.1.1) + nokogiri (>= 1.8.5) + rack (>= 2.2.4) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.1) + actionpack (= 7.1.1) + activerecord (= 7.1.1) + activestorage (= 7.1.1) + activesupport (= 7.1.1) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.1.1) + activesupport (= 7.1.1) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.1.1) + activesupport (= 7.1.1) + globalid (>= 0.3.6) + activemodel (7.1.1) + activesupport (= 7.1.1) + activerecord (7.1.1) + activemodel (= 7.1.1) + activesupport (= 7.1.1) + timeout (>= 0.4.0) + activestorage (7.1.1) + actionpack (= 7.1.1) + activejob (= 7.1.1) + activerecord (= 7.1.1) + activesupport (= 7.1.1) + marcel (~> 1.0) + activesupport (7.1.1) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + minitest (>= 5.1) + mutex_m + tzinfo (~> 2.0) + ast (2.4.2) + base64 (0.1.1) + bcrypt (3.1.19) + bigdecimal (3.1.4) + bootsnap (1.16.0) + msgpack (~> 1.2) + builder (3.2.4) + concurrent-ruby (1.2.2) + connection_pool (2.4.1) + crass (1.0.6) + date (3.3.3) + debug (1.8.0) + irb (>= 1.5.0) + reline (>= 0.3.1) + devise (4.9.3) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) + drb (2.1.1) + ruby2_keywords + erubi (1.12.0) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.1) + concurrent-ruby (~> 1.0) + io-console (0.6.0) + irb (1.8.3) + rdoc + reline (>= 0.3.8) + json (2.6.3) + language_server-protocol (3.17.0.3) + loofah (2.21.4) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.8.1) + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.0.2) + mini_mime (1.1.5) + minitest (5.20.0) + msgpack (1.7.2) + mutex_m (0.1.2) + net-imap (0.4.2) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.1) + timeout + net-smtp (0.4.0) + net-protocol + nio4r (2.5.9) + nokogiri (1.15.4-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.15.4-x86_64-linux) + racc (~> 1.4) + orm_adapter (0.5.0) + parallel (1.23.0) + parser (3.2.2.4) + ast (~> 2.4.1) + racc + pg (1.5.4) + psych (5.1.1.1) + stringio + puma (6.4.0) + nio4r (~> 2.0) + racc (1.7.1) + rack (3.0.8) + rack-cors (2.0.1) + rack (>= 2.0.0) + rack-session (2.0.0) + rack (>= 3.0.0) + rack-test (2.1.0) + rack (>= 1.3) + rackup (2.1.0) + rack (>= 3) + webrick (~> 1.8) + rails (7.1.1) + actioncable (= 7.1.1) + actionmailbox (= 7.1.1) + actionmailer (= 7.1.1) + actionpack (= 7.1.1) + actiontext (= 7.1.1) + actionview (= 7.1.1) + activejob (= 7.1.1) + activemodel (= 7.1.1) + activerecord (= 7.1.1) + activestorage (= 7.1.1) + activesupport (= 7.1.1) + bundler (>= 1.15.0) + railties (= 7.1.1) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + railties (7.1.1) + actionpack (= 7.1.1) + activesupport (= 7.1.1) + irb + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.0.6) + rdoc (6.5.0) + psych (>= 4.0.0) + regexp_parser (2.8.2) + reline (0.3.9) + io-console (~> 0.5) + responders (3.1.1) + actionpack (>= 5.2) + railties (>= 5.2) + rexml (3.2.6) + rubocop (1.57.1) + base64 (~> 0.1.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.4) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + ruby-progressbar (1.13.0) + ruby2_keywords (0.0.5) + stringio (3.0.8) + thor (1.3.0) + timeout (0.4.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.5.0) + warden (1.2.9) + rack (>= 2.0.9) + webrick (1.8.1) + websocket-driver (0.7.6) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + zeitwerk (2.6.12) + +PLATFORMS + x86_64-darwin-22 + x86_64-linux + +DEPENDENCIES + bootsnap + debug + devise + pg (~> 1.1) + puma (>= 5.0) + rack-cors + rails (~> 7.1.1) + rubocop (>= 1.0, < 2.0) + tzinfo-data + +RUBY VERSION + ruby 3.2.2p53 + +BUNDLED WITH + 2.4.21 From a4dc5eeae80e210bbfe1670d91a02c185cfb5d02 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:17:09 -0300 Subject: [PATCH 06/90] Create the new rails app with api and postgre command generating all the files --- .dockerignore | 31 ++ .gitattributes | 9 + .gitignore | 33 ++ .ruby-version | 1 + Dockerfile | 59 ++++ README.md | 24 ++ Rakefile | 6 + app/channels/application_cable/channel.rb | 4 + app/channels/application_cable/connection.rb | 4 + app/controllers/application_controller.rb | 2 + app/controllers/concerns/.keep | 0 app/controllers/users_controller.rb | 4 + app/jobs/application_job.rb | 7 + app/mailers/application_mailer.rb | 4 + app/models/application_record.rb | 3 + app/models/car.rb | 2 + app/models/concerns/.keep | 0 app/models/reservation.rb | 4 + app/models/user.rb | 6 + app/views/layouts/mailer.html.erb | 13 + app/views/layouts/mailer.text.erb | 1 + bin/bundle | 109 ++++++ bin/docker-entrypoint | 8 + bin/rails | 4 + bin/rake | 4 + bin/setup | 33 ++ config.ru | 6 + config/application.rb | 32 ++ config/boot.rb | 4 + config/cable.yml | 10 + config/credentials.yml.enc | 1 + config/database.yml | 84 +++++ config/environment.rb | 5 + config/environments/development.rb | 71 ++++ config/environments/production.rb | 90 +++++ config/environments/test.rb | 64 ++++ config/initializers/cors.rb | 8 + config/initializers/devise.rb | 313 ++++++++++++++++++ .../initializers/filter_parameter_logging.rb | 8 + config/initializers/inflections.rb | 16 + config/locales/devise.en.yml | 65 ++++ config/locales/en.yml | 31 ++ config/puma.rb | 35 ++ config/routes.rb | 12 + config/storage.yml | 34 ++ lib/tasks/.keep | 0 log/.keep | 0 public/robots.txt | 1 + storage/.keep | 0 .../application_cable/connection_test.rb | 13 + test/controllers/.keep | 0 test/controllers/users_controller_test.rb | 8 + test/fixtures/cars.yml | 21 ++ test/fixtures/files/.keep | 0 test/fixtures/reservations.yml | 17 + test/fixtures/users.yml | 11 + test/integration/.keep | 0 test/mailers/.keep | 0 test/models/.keep | 0 test/models/car_test.rb | 7 + test/models/reservation_test.rb | 7 + test/models/user_test.rb | 7 + test/test_helper.rb | 15 + tmp/.keep | 0 tmp/pids/.keep | 0 tmp/storage/.keep | 0 vendor/.keep | 0 67 files changed, 1371 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .ruby-version create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 Rakefile create mode 100644 app/channels/application_cable/channel.rb create mode 100644 app/channels/application_cable/connection.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/concerns/.keep create mode 100644 app/controllers/users_controller.rb create mode 100644 app/jobs/application_job.rb create mode 100644 app/mailers/application_mailer.rb create mode 100644 app/models/application_record.rb create mode 100644 app/models/car.rb create mode 100644 app/models/concerns/.keep create mode 100644 app/models/reservation.rb create mode 100644 app/models/user.rb create mode 100644 app/views/layouts/mailer.html.erb create mode 100644 app/views/layouts/mailer.text.erb create mode 100755 bin/bundle create mode 100755 bin/docker-entrypoint create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/setup create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/cable.yml create mode 100644 config/credentials.yml.enc create mode 100644 config/database.yml create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/initializers/cors.rb create mode 100644 config/initializers/devise.rb create mode 100644 config/initializers/filter_parameter_logging.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/locales/devise.en.yml create mode 100644 config/locales/en.yml create mode 100644 config/puma.rb create mode 100644 config/routes.rb create mode 100644 config/storage.yml create mode 100644 lib/tasks/.keep create mode 100644 log/.keep create mode 100644 public/robots.txt create mode 100644 storage/.keep create mode 100644 test/channels/application_cable/connection_test.rb create mode 100644 test/controllers/.keep create mode 100644 test/controllers/users_controller_test.rb create mode 100644 test/fixtures/cars.yml create mode 100644 test/fixtures/files/.keep create mode 100644 test/fixtures/reservations.yml create mode 100644 test/fixtures/users.yml create mode 100644 test/integration/.keep create mode 100644 test/mailers/.keep create mode 100644 test/models/.keep create mode 100644 test/models/car_test.rb create mode 100644 test/models/reservation_test.rb create mode 100644 test/models/user_test.rb create mode 100644 test/test_helper.rb create mode 100644 tmp/.keep create mode 100644 tmp/pids/.keep create mode 100644 tmp/storage/.keep create mode 100644 vendor/.keep diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..bb56daf --- /dev/null +++ b/.dockerignore @@ -0,0 +1,31 @@ +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. + +# Ignore git directory. +/.git/ + +# Ignore bundler config. +/.bundle + +# Ignore all environment files (except templates). +/.env* +!/.env*.erb + +# Ignore all default key files. +/config/master.key +/config/credentials/*.key + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/.keep diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8dc4323 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +# See https://git-scm.com/docs/gitattributes for more about git attribute files. + +# Mark the database schema as having been generated. +db/schema.rb linguist-generated + +# Mark any vendored files as having been vendored. +vendor/* linguist-vendored +config/credentials/*.yml.enc diff=rails_credentials +config/credentials.yml.enc diff=rails_credentials diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e6b54f --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore all environment files (except templates). +/.env* +!/.env*.erb + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/ +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/ +!/tmp/storage/.keep + +# Ignore master key for decrypting credentials and more. +/config/master.key diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..9e79f6c --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +ruby-3.2.2 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..11d58b9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,59 @@ +# syntax = docker/dockerfile:1 + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile +ARG RUBY_VERSION=3.2.2 +FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base + +# Rails app lives here +WORKDIR /rails + +# Set production environment +ENV RAILS_ENV="production" \ + BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" \ + BUNDLE_WITHOUT="development" + + +# Throw-away build stage to reduce size of final image +FROM base as build + +# Install packages needed to build gems +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config + +# Install application gems +COPY Gemfile Gemfile.lock ./ +RUN bundle install && \ + rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ + bundle exec bootsnap precompile --gemfile + +# Copy application code +COPY . . + +# Precompile bootsnap code for faster boot times +RUN bundle exec bootsnap precompile app/ lib/ + + +# Final stage for app image +FROM base + +# Install packages needed for deployment +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libvips postgresql-client && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Copy built artifacts: gems, application +COPY --from=build /usr/local/bundle /usr/local/bundle +COPY --from=build /rails /rails + +# Run and own only the runtime files as a non-root user for security +RUN useradd rails --create-home --shell /bin/bash && \ + chown -R rails:rails db log storage tmp +USER rails:rails + +# Entrypoint prepares the database. +ENTRYPOINT ["/rails/bin/docker-entrypoint"] + +# Start the server by default, this can be overwritten at runtime +EXPOSE 3000 +CMD ["./bin/rails", "server"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..7db80e4 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..9a5ea73 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative "config/application" + +Rails.application.load_tasks diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb new file mode 100644 index 0000000..d672697 --- /dev/null +++ b/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb new file mode 100644 index 0000000..0ff5442 --- /dev/null +++ b/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..4ac8823 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::API +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..3004a55 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,4 @@ +class UsersController < ApplicationController + def index + end +end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 0000000..d394c3d --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,7 @@ +class ApplicationJob < ActiveJob::Base + # Automatically retry jobs that encountered a deadlock + # retry_on ActiveRecord::Deadlocked + + # Most jobs are safe to ignore if the underlying records are no longer available + # discard_on ActiveJob::DeserializationError +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 0000000..3c34c81 --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout "mailer" +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 0000000..b63caeb --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/app/models/car.rb b/app/models/car.rb new file mode 100644 index 0000000..ce30b91 --- /dev/null +++ b/app/models/car.rb @@ -0,0 +1,2 @@ +class Car < ApplicationRecord +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/reservation.rb b/app/models/reservation.rb new file mode 100644 index 0000000..eb376f5 --- /dev/null +++ b/app/models/reservation.rb @@ -0,0 +1,4 @@ +class Reservation < ApplicationRecord + belongs_to :user + belongs_to :car +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..4756799 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,6 @@ +class User < ApplicationRecord + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable + devise :database_authenticatable, :registerable, + :recoverable, :rememberable, :validatable +end diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 0000000..3aac900 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 0000000..37f0bdd --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 0000000..42c7fd7 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,109 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'bundle' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "rubygems" + +m = Module.new do + module_function + + def invoked_as_script? + File.expand_path($0) == File.expand_path(__FILE__) + end + + def env_var_version + ENV["BUNDLER_VERSION"] + end + + def cli_arg_version + return unless invoked_as_script? # don't want to hijack other binstubs + return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` + bundler_version = nil + update_index = nil + ARGV.each_with_index do |a, i| + if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN + bundler_version = a + end + next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ + bundler_version = $1 + update_index = i + end + bundler_version + end + + def gemfile + gemfile = ENV["BUNDLE_GEMFILE"] + return gemfile if gemfile && !gemfile.empty? + + File.expand_path("../Gemfile", __dir__) + end + + def lockfile + lockfile = + case File.basename(gemfile) + when "gems.rb" then gemfile.sub(/\.rb$/, ".locked") + else "#{gemfile}.lock" + end + File.expand_path(lockfile) + end + + def lockfile_version + return unless File.file?(lockfile) + lockfile_contents = File.read(lockfile) + return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ + Regexp.last_match(1) + end + + def bundler_requirement + @bundler_requirement ||= + env_var_version || + cli_arg_version || + bundler_requirement_for(lockfile_version) + end + + def bundler_requirement_for(version) + return "#{Gem::Requirement.default}.a" unless version + + bundler_gem_version = Gem::Version.new(version) + + bundler_gem_version.approximate_recommendation + end + + def load_bundler! + ENV["BUNDLE_GEMFILE"] ||= gemfile + + activate_bundler + end + + def activate_bundler + gem_error = activation_error_handling do + gem "bundler", bundler_requirement + end + return if gem_error.nil? + require_error = activation_error_handling do + require "bundler/version" + end + return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) + warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" + exit 42 + end + + def activation_error_handling + yield + nil + rescue StandardError, LoadError => e + e + end +end + +m.load_bundler! + +if m.invoked_as_script? + load Gem.bin_path("bundler", "bundle") +end diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint new file mode 100755 index 0000000..67ef493 --- /dev/null +++ b/bin/docker-entrypoint @@ -0,0 +1,8 @@ +#!/bin/bash -e + +# If running the rails server then create or migrate existing database +if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then + ./bin/rails db:prepare +fi + +exec "${@}" diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..efc0377 --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..4fbf10b --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative "../config/boot" +require "rake" +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..3cd5a9d --- /dev/null +++ b/bin/setup @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby +require "fileutils" + +# path to your application root. +APP_ROOT = File.expand_path("..", __dir__) + +def system!(*args) + system(*args, exception: true) +end + +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. + # Add necessary setup steps to this file. + + puts "== Installing dependencies ==" + system! "gem install bundler --conservative" + system("bundle check") || system!("bundle install") + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" + # end + + puts "\n== Preparing database ==" + system! "bin/rails db:prepare" + + puts "\n== Removing old logs and tempfiles ==" + system! "bin/rails log:clear tmp:clear" + + puts "\n== Restarting application server ==" + system! "bin/rails restart" +end diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..4a3c09a --- /dev/null +++ b/config.ru @@ -0,0 +1,6 @@ +# This file is used by Rack-based servers to start the application. + +require_relative "config/environment" + +run Rails.application +Rails.application.load_server diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000..352431d --- /dev/null +++ b/config/application.rb @@ -0,0 +1,32 @@ +require_relative "boot" + +require "rails/all" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module FinalCapstoneBackEnd + class Application < Rails::Application + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 7.1 + + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib(ignore: %w(assets tasks)) + + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + # + # config.time_zone = "Central Time (US & Canada)" + # config.eager_load_paths << Rails.root.join("extras") + + # Only loads a smaller set of middleware suitable for API only apps. + # Middleware like session, flash, cookies can be added back manually. + # Skip views, helpers and assets when generating a new resource. + config.api_only = true + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..988a5dd --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,4 @@ +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" # Set up gems listed in the Gemfile. +require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 0000000..f2f2cad --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: test + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: final_capstone_back_end_production diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc new file mode 100644 index 0000000..b3baafa --- /dev/null +++ b/config/credentials.yml.enc @@ -0,0 +1 @@ +hAMsQeXRg/cvleA8Kk13DbBsjUOjI9VjtKfKRZeogkZWmd41D7yACbA0yhuM7z1kCfi9m8wgymw9soxwGwv6/WmmHEMQTUMGMLxpsQ84bE80d/yIHEMVAvGjvYmS1ITYy7+McElWJ80+XuT4dO7CUgBBApKPlm0Im40XuNV02ld6lVPBVtq9u1zJ+9hoLRoYOmSo7tStQrDypbtGaxg6ifHDu75nzAzTKifDw7CnKbkEkPcvWUpacMy01z1W1XGC3xW1EhR8ejB8ZoUWKFsh81vodD2nvPrlwwrm1keH6NViOre9WusuQoVKI744UBgp1J6La9ujLbfuUspc04fO7UCwmcOxrbsFTZ/Dbj+OdLKEYMIZg/bfR4bZV1qNN15WATPxLj8TbXpK0P5I6jOyNnyH+KMg--RJbmBNkT+v1staIj--LPuxVzc38D6DizARIH9RGw== \ No newline at end of file diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..7bde612 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,84 @@ +# PostgreSQL. Versions 9.3 and up are supported. +# +# Install the pg driver: +# gem install pg +# On macOS with Homebrew: +# gem install pg -- --with-pg-config=/usr/local/bin/pg_config +# On Windows: +# gem install pg +# Choose the win32 build. +# Install PostgreSQL and put its /bin directory on your path. +# +# Configure Using Gemfile +# gem "pg" +# +default: &default + adapter: postgresql + encoding: unicode + # For details on connection pooling, see Rails configuration guide + # https://guides.rubyonrails.org/configuring.html#database-pooling + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + +development: + <<: *default + database: final_capstone_back_end_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: final_capstone_back_end + + # The password associated with the PostgreSQL role (username). + #password: + + # Connect on a TCP socket. Omitted by default since the client uses a + # domain socket that doesn't need configuration. Windows does not have + # domain sockets, so uncomment these lines. + #host: localhost + + # The TCP port the server listens on. Defaults to 5432. + # If your server runs on a different port number, change accordingly. + #port: 5432 + + # Schema search path. The server defaults to $user,public + #schema_search_path: myapp,sharedapp,public + + # Minimum log levels, in increasing order: + # debug5, debug4, debug3, debug2, debug1, + # log, notice, warning, error, fatal, and panic + # Defaults to warning. + #min_messages: notice + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: final_capstone_back_end_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 +# ever seen by anyone, they now have access to your database. +# +# Instead, provide the password or a full connection URL as an environment +# variable when you boot the app. For example: +# +# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" +# +# If the connection URL is provided in the special DATABASE_URL environment +# variable, Rails will automatically merge its configuration values on top of +# the values provided in this file. Alternatively, you can specify a connection +# URL environment variable explicitly: +# +# production: +# url: <%= ENV["MY_APP_DATABASE_URL"] %> +# +# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database +# for a full overview on how database connection configuration can be specified. +# +production: + <<: *default + database: final_capstone_back_end_production + username: final_capstone_back_end + password: <%= ENV["FINAL_CAPSTONE_BACK_END_DATABASE_PASSWORD"] %> diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..cac5315 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative "application" + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..e701c0d --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,71 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } + # In the development environment your application's code is reloaded any time + # it changes. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.enable_reloading = true + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable server timing + config.server_timing = true + + # Enable/disable caching. By default caching is disabled. + # Run rails dev:cache to toggle caching. + if Rails.root.join("tmp/caching-dev.txt").exist? + config.cache_store = :memory_store + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=#{2.days.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Highlight code that enqueued background job in logs. + config.active_job.verbose_enqueue_logs = true + + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + + # Raise error when a before_action's only/except options reference missing actions + config.action_controller.raise_on_missing_callback_actions = true +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..e99a554 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,90 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.enable_reloading = false + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + + # Enable static file serving from the `/public` folder (turn off if using NGINX/Apache for it). + config.public_file_server.enabled = true + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.asset_host = "http://assets.example.com" + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache + # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Mount Action Cable outside main process or domain. + # config.action_cable.mount_path = nil + # config.action_cable.url = "wss://example.com/cable" + # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] + + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. + # config.assume_ssl = true + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + config.force_ssl = true + + # Log to STDOUT by default + config.logger = ActiveSupport::Logger.new(STDOUT) + .tap { |logger| logger.formatter = ::Logger::Formatter.new } + .then { |logger| ActiveSupport::TaggedLogging.new(logger) } + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Info include generic and useful information about system operation, but avoids logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). If you + # want to log everything, set the level to "debug". + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # 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 = "final_capstone_back_end_production" + + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Don't log any deprecations. + config.active_support.report_deprecations = false + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..0dda9f9 --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,64 @@ +require "active_support/core_ext/integer/time" + +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false + + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. + config.eager_load = ENV["CI"].present? + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=#{1.hour.to_i}" + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + config.cache_store = :null_store + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = :rescuable + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Raise error when a before_action's only/except options reference missing actions + config.action_controller.raise_on_missing_callback_actions = true +end diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb new file mode 100644 index 0000000..6cb3ec6 --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,8 @@ +Rails.application.config.middleware.insert_before 0, Rack::Cors do + allow do + origins 'http://localhost:3001' + resource '*', + headers: :any, + methods: [:get, :post, :put, :patch, :delete, :options, :head] + end + end \ No newline at end of file diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb new file mode 100644 index 0000000..8c51dc2 --- /dev/null +++ b/config/initializers/devise.rb @@ -0,0 +1,313 @@ +# frozen_string_literal: true + +# Assuming you have not yet modified this file, each configuration option below +# is set to its default value. Note that some are commented out while others +# are not: uncommented lines are intended to protect your configuration from +# breaking changes in upgrades (i.e., in the event that future versions of +# Devise change the default values for those options). +# +# Use this hook to configure devise mailer, warden hooks and so forth. +# Many of these configuration options can be set straight in your model. +Devise.setup do |config| + # The secret key used by Devise. Devise uses this key to generate + # random tokens. Changing this key will render invalid all existing + # confirmation, reset password and unlock tokens in the database. + # Devise will use the `secret_key_base` as its `secret_key` + # by default. You can change it below and use your own secret key. + # config.secret_key = '33ecd5075b4af2bc6c0ad66ea4bf05a64112604a82dcd7e48aa68d4fe8459f570cec4a9a089b916ab79126224c9b954cb4f862e376cfcee8dd18d2e10a66f120' + + # ==> Controller configuration + # Configure the parent class to the devise controllers. + # config.parent_controller = 'DeviseController' + + # ==> Mailer Configuration + # Configure the e-mail address which will be shown in Devise::Mailer, + # note that it will be overwritten if you use your own mailer class + # with default "from" parameter. + config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' + + # Configure the class responsible to send e-mails. + # config.mailer = 'Devise::Mailer' + + # Configure the parent class responsible to send e-mails. + # config.parent_mailer = 'ActionMailer::Base' + + # ==> ORM configuration + # Load and configure the ORM. Supports :active_record (default) and + # :mongoid (bson_ext recommended) by default. Other ORMs may be + # available as additional gems. + require 'devise/orm/active_record' + + # ==> Configuration for any authentication mechanism + # Configure which keys are used when authenticating a user. The default is + # just :email. You can configure it to use [:username, :subdomain], so for + # authenticating a user, both parameters are required. Remember that those + # parameters are used only when authenticating and not when retrieving from + # session. If you need permissions, you should implement that in a before filter. + # You can also supply a hash where the value is a boolean determining whether + # or not authentication should be aborted when the value is not present. + # config.authentication_keys = [:email] + + # Configure parameters from the request object used for authentication. Each entry + # given should be a request method and it will automatically be passed to the + # find_for_authentication method and considered in your model lookup. For instance, + # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. + # The same considerations mentioned for authentication_keys also apply to request_keys. + # config.request_keys = [] + + # Configure which authentication keys should be case-insensitive. + # These keys will be downcased upon creating or modifying a user and when used + # to authenticate or find a user. Default is :email. + config.case_insensitive_keys = [:email] + + # Configure which authentication keys should have whitespace stripped. + # These keys will have whitespace before and after removed upon creating or + # modifying a user and when used to authenticate or find a user. Default is :email. + config.strip_whitespace_keys = [:email] + + # Tell if authentication through request.params is enabled. True by default. + # It can be set to an array that will enable params authentication only for the + # given strategies, for example, `config.params_authenticatable = [:database]` will + # enable it only for database (email + password) authentication. + # config.params_authenticatable = true + + # Tell if authentication through HTTP Auth is enabled. False by default. + # It can be set to an array that will enable http authentication only for the + # given strategies, for example, `config.http_authenticatable = [:database]` will + # enable it only for database authentication. + # For API-only applications to support authentication "out-of-the-box", you will likely want to + # enable this with :database unless you are using a custom strategy. + # The supported strategies are: + # :database = Support basic authentication with authentication key + password + # config.http_authenticatable = false + + # If 401 status code should be returned for AJAX requests. True by default. + # config.http_authenticatable_on_xhr = true + + # The realm used in Http Basic Authentication. 'Application' by default. + # config.http_authentication_realm = 'Application' + + # It will change confirmation, password recovery and other workflows + # to behave the same regardless if the e-mail provided was right or wrong. + # Does not affect registerable. + # config.paranoid = true + + # By default Devise will store the user in session. You can skip storage for + # particular strategies by setting this option. + # Notice that if you are skipping storage for all authentication paths, you + # may want to disable generating routes to Devise's sessions controller by + # passing skip: :sessions to `devise_for` in your config/routes.rb + config.skip_session_storage = [:http_auth] + + # By default, Devise cleans up the CSRF token on authentication to + # avoid CSRF token fixation attacks. This means that, when using AJAX + # requests for sign in and sign up, you need to get a new CSRF token + # from the server. You can disable this option at your own risk. + # config.clean_up_csrf_token_on_authentication = true + + # When false, Devise will not attempt to reload routes on eager load. + # This can reduce the time taken to boot the app but if your application + # requires the Devise mappings to be loaded during boot time the application + # won't boot properly. + # config.reload_routes = true + + # ==> Configuration for :database_authenticatable + # For bcrypt, this is the cost for hashing the password and defaults to 12. If + # using other algorithms, it sets how many times you want the password to be hashed. + # The number of stretches used for generating the hashed password are stored + # with the hashed password. This allows you to change the stretches without + # invalidating existing passwords. + # + # Limiting the stretches to just one in testing will increase the performance of + # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use + # a value less than 10 in other environments. Note that, for bcrypt (the default + # algorithm), the cost increases exponentially with the number of stretches (e.g. + # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). + config.stretches = Rails.env.test? ? 1 : 12 + + # Set up a pepper to generate the hashed password. + # config.pepper = 'cb68259e84b3e1053daaa9b801f065679c76a60403af285154d99333d2aed5dc6bda9f10652bbbee2c1fa669d5d4a0b910856cea12f6baa81f029cd088175466' + + # Send a notification to the original email when the user's email is changed. + # config.send_email_changed_notification = false + + # Send a notification email when the user's password is changed. + # config.send_password_change_notification = false + + # ==> Configuration for :confirmable + # A period that the user is allowed to access the website even without + # confirming their account. For instance, if set to 2.days, the user will be + # able to access the website for two days without confirming their account, + # access will be blocked just in the third day. + # You can also set it to nil, which will allow the user to access the website + # without confirming their account. + # Default is 0.days, meaning the user cannot access the website without + # confirming their account. + # config.allow_unconfirmed_access_for = 2.days + + # A period that the user is allowed to confirm their account before their + # token becomes invalid. For example, if set to 3.days, the user can confirm + # their account within 3 days after the mail was sent, but on the fourth day + # their account can't be confirmed with the token any more. + # Default is nil, meaning there is no restriction on how long a user can take + # before confirming their account. + # config.confirm_within = 3.days + + # If true, requires any email changes to be confirmed (exactly the same way as + # initial account confirmation) to be applied. Requires additional unconfirmed_email + # db field (see migrations). Until confirmed, new email is stored in + # unconfirmed_email column, and copied to email column on successful confirmation. + config.reconfirmable = true + + # Defines which key will be used when confirming an account + # config.confirmation_keys = [:email] + + # ==> Configuration for :rememberable + # The time the user will be remembered without asking for credentials again. + # config.remember_for = 2.weeks + + # Invalidates all the remember me tokens when the user signs out. + config.expire_all_remember_me_on_sign_out = true + + # If true, extends the user's remember period when remembered via cookie. + # config.extend_remember_period = false + + # Options to be passed to the created cookie. For instance, you can set + # secure: true in order to force SSL only cookies. + # config.rememberable_options = {} + + # ==> Configuration for :validatable + # Range for password length. + config.password_length = 6..128 + + # Email regex used to validate email formats. It simply asserts that + # one (and only one) @ exists in the given string. This is mainly + # to give user feedback and not to assert the e-mail validity. + config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ + + # ==> Configuration for :timeoutable + # The time you want to timeout the user session without activity. After this + # time the user will be asked for credentials again. Default is 30 minutes. + # config.timeout_in = 30.minutes + + # ==> Configuration for :lockable + # Defines which strategy will be used to lock an account. + # :failed_attempts = Locks an account after a number of failed attempts to sign in. + # :none = No lock strategy. You should handle locking by yourself. + # config.lock_strategy = :failed_attempts + + # Defines which key will be used when locking and unlocking an account + # config.unlock_keys = [:email] + + # Defines which strategy will be used to unlock an account. + # :email = Sends an unlock link to the user email + # :time = Re-enables login after a certain amount of time (see :unlock_in below) + # :both = Enables both strategies + # :none = No unlock strategy. You should handle unlocking by yourself. + # config.unlock_strategy = :both + + # Number of authentication tries before locking an account if lock_strategy + # is failed attempts. + # config.maximum_attempts = 20 + + # Time interval to unlock the account if :time is enabled as unlock_strategy. + # config.unlock_in = 1.hour + + # Warn on the last attempt before the account is locked. + # config.last_attempt_warning = true + + # ==> Configuration for :recoverable + # + # Defines which key will be used when recovering the password for an account + # config.reset_password_keys = [:email] + + # Time interval you can reset your password with a reset password key. + # Don't put a too small interval or your users won't have the time to + # change their passwords. + config.reset_password_within = 6.hours + + # When set to false, does not sign a user in automatically after their password is + # reset. Defaults to true, so a user is signed in automatically after a reset. + # config.sign_in_after_reset_password = true + + # ==> Configuration for :encryptable + # Allow you to use another hashing or encryption algorithm besides bcrypt (default). + # You can use :sha1, :sha512 or algorithms from others authentication tools as + # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 + # for default behavior) and :restful_authentication_sha1 (then you should set + # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). + # + # Require the `devise-encryptable` gem when using anything other than bcrypt + # config.encryptor = :sha512 + + # ==> Scopes configuration + # Turn scoped views on. Before rendering "sessions/new", it will first check for + # "users/sessions/new". It's turned off by default because it's slower if you + # are using only default views. + # config.scoped_views = false + + # Configure the default scope given to Warden. By default it's the first + # devise role declared in your routes (usually :user). + # config.default_scope = :user + + # Set this configuration to false if you want /users/sign_out to sign out + # only the current scope. By default, Devise signs out all scopes. + # config.sign_out_all_scopes = true + + # ==> Navigation configuration + # Lists the formats that should be treated as navigational. Formats like + # :html should redirect to the sign in page when the user does not have + # access, but formats like :xml or :json, should return 401. + # + # If you have any extra navigational formats, like :iphone or :mobile, you + # should add them to the navigational formats lists. + # + # The "*/*" below is required to match Internet Explorer requests. + # config.navigational_formats = ['*/*', :html, :turbo_stream] + + # The default HTTP method used to sign out a resource. Default is :delete. + config.sign_out_via = :delete + + # ==> OmniAuth + # Add a new OmniAuth provider. Check the wiki for more information on setting + # up on your models and hooks. + # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' + + # ==> Warden configuration + # If you want to use other strategies, that are not supported by Devise, or + # change the failure app, you can configure them inside the config.warden block. + # + # config.warden do |manager| + # manager.intercept_401 = false + # manager.default_strategies(scope: :user).unshift :some_external_strategy + # end + + # ==> Mountable engine configurations + # When using Devise inside an engine, let's call it `MyEngine`, and this engine + # is mountable, there are some extra configurations to be taken into account. + # The following options are available, assuming the engine is mounted as: + # + # mount MyEngine, at: '/my_engine' + # + # The router that invoked `devise_for`, in the example above, would be: + # config.router_name = :my_engine + # + # When using OmniAuth, Devise cannot automatically set OmniAuth path, + # so you need to do it manually. For the users scope, it would be: + # config.omniauth_path_prefix = '/my_engine/users/auth' + + # ==> Hotwire/Turbo configuration + # When using Devise with Hotwire/Turbo, the http status for error responses + # and some redirects must match the following. The default in Devise for existing + # apps is `200 OK` and `302 Found` respectively, but new apps are generated with + # these new defaults that match Hotwire/Turbo behavior. + # Note: These might become the new default in future versions of Devise. + config.responder.error_status = :unprocessable_entity + config.responder.redirect_status = :see_other + + # ==> Configuration for :registerable + + # When set to false, does not sign a user in automatically after their password is + # changed. Defaults to true, so a user is signed in automatically after changing a password. + # config.sign_in_after_change_password = true +end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..c2d89e2 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. +Rails.application.config.filter_parameters += [ + :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn +] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..3860f65 --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, "\\1en" +# inflect.singular /^(ox)en/i, "\\1" +# inflect.irregular "person", "people" +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym "RESTful" +# end diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml new file mode 100644 index 0000000..260e1c4 --- /dev/null +++ b/config/locales/devise.en.yml @@ -0,0 +1,65 @@ +# Additional translations at https://github.com/heartcombo/devise/wiki/I18n + +en: + devise: + confirmations: + confirmed: "Your email address has been successfully confirmed." + send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." + failure: + already_authenticated: "You are already signed in." + inactive: "Your account is not activated yet." + invalid: "Invalid %{authentication_keys} or password." + locked: "Your account is locked." + last_attempt: "You have one more attempt before your account is locked." + not_found_in_database: "Invalid %{authentication_keys} or password." + timeout: "Your session expired. Please sign in again to continue." + unauthenticated: "You need to sign in or sign up before continuing." + unconfirmed: "You have to confirm your email address before continuing." + mailer: + confirmation_instructions: + subject: "Confirmation instructions" + reset_password_instructions: + subject: "Reset password instructions" + unlock_instructions: + subject: "Unlock instructions" + email_changed: + subject: "Email Changed" + password_change: + subject: "Password Changed" + omniauth_callbacks: + failure: "Could not authenticate you from %{kind} because \"%{reason}\"." + success: "Successfully authenticated from %{kind} account." + passwords: + no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." + send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." + updated: "Your password has been changed successfully. You are now signed in." + updated_not_active: "Your password has been changed successfully." + registrations: + destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." + signed_up: "Welcome! You have signed up successfully." + signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." + signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." + signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account." + update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address." + updated: "Your account has been updated successfully." + updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again." + sessions: + signed_in: "Signed in successfully." + signed_out: "Signed out successfully." + already_signed_out: "Signed out successfully." + unlocks: + send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." + send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." + unlocked: "Your account has been unlocked successfully. Please sign in to continue." + errors: + messages: + already_confirmed: "was already confirmed, please try signing in" + confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" + expired: "has expired, please request a new one" + not_found: "not found" + not_locked: "was not locked" + not_saved: + one: "1 error prohibited this %{resource} from being saved:" + other: "%{count} errors prohibited this %{resource} from being saved:" diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..6c349ae --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,31 @@ +# Files in the config/locales directory are used for internationalization and +# are automatically loaded by Rails. If you want to use locales other than +# English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t "hello" +# +# In views, this is aliased to just `t`: +# +# <%= t("hello") %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more about the API, please read the Rails Internationalization guide +# at https://guides.rubyonrails.org/i18n.html. +# +# Be aware that YAML interprets the following case-insensitive strings as +# booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings +# must be quoted to be interpreted as strings. For example: +# +# en: +# "yes": yup +# enabled: "ON" + +en: + hello: "Hello world" diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 0000000..afa809b --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,35 @@ +# This configuration file will be evaluated by Puma. The top-level methods that +# are invoked here are part of Puma's configuration DSL. For more information +# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. + +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } +min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } +threads min_threads_count, max_threads_count + +# Specifies that the worker count should equal the number of processors in production. +if ENV["RAILS_ENV"] == "production" + require "concurrent-ruby" + worker_count = Integer(ENV.fetch("WEB_CONCURRENCY") { Concurrent.physical_processor_count }) + workers worker_count if worker_count > 1 +end + +# Specifies the `worker_timeout` threshold that Puma will use to wait before +# terminating a worker in development environments. +worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the `pidfile` that Puma will use. +pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } + +# Allow puma to be restarted by `bin/rails restart` command. +plugin :tmp_restart diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..b8e55f6 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,12 @@ +Rails.application.routes.draw do + get 'users/index' + devise_for :users + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + + # 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. + get "up" => "rails/health#show", as: :rails_health_check + + # Defines the root path route ("/") + # root "posts#index" +end diff --git a/config/storage.yml b/config/storage.yml new file mode 100644 index 0000000..4942ab6 --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket-<%= Rails.env %> + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket-<%= Rails.env %> + +# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name-<%= Rails.env %> + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/log/.keep b/log/.keep new file mode 100644 index 0000000..e69de29 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..c19f78a --- /dev/null +++ b/public/robots.txt @@ -0,0 +1 @@ +# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/storage/.keep b/storage/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/channels/application_cable/connection_test.rb b/test/channels/application_cable/connection_test.rb new file mode 100644 index 0000000..6340bf9 --- /dev/null +++ b/test/channels/application_cable/connection_test.rb @@ -0,0 +1,13 @@ +require "test_helper" + +module ApplicationCable + class ConnectionTest < ActionCable::Connection::TestCase + # test "connects with cookies" do + # cookies.signed[:user_id] = 42 + # + # connect + # + # assert_equal connection.user_id, "42" + # end + end +end diff --git a/test/controllers/.keep b/test/controllers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb new file mode 100644 index 0000000..4938283 --- /dev/null +++ b/test/controllers/users_controller_test.rb @@ -0,0 +1,8 @@ +require "test_helper" + +class UsersControllerTest < ActionDispatch::IntegrationTest + test "should get index" do + get users_index_url + assert_response :success + end +end diff --git a/test/fixtures/cars.yml b/test/fixtures/cars.yml new file mode 100644 index 0000000..14ab3ef --- /dev/null +++ b/test/fixtures/cars.yml @@ -0,0 +1,21 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + description: MyText + deposit: 1 + finance_fee: 1 + option_to_purchase_fee: 1 + total_amount_payable: 1 + duration: 1 + removed: false + +two: + name: MyString + description: MyText + deposit: 1 + finance_fee: 1 + option_to_purchase_fee: 1 + total_amount_payable: 1 + duration: 1 + removed: false diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/reservations.yml b/test/fixtures/reservations.yml new file mode 100644 index 0000000..c164be0 --- /dev/null +++ b/test/fixtures/reservations.yml @@ -0,0 +1,17 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + user: one + car: one + start_time: 2023-10-25 18:57:55 + end_time: 2023-10-25 18:57:55 + available: false + city: MyString + +two: + user: two + car: two + start_time: 2023-10-25 18:57:55 + end_time: 2023-10-25 18:57:55 + available: false + city: MyString diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..d7a3329 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the "{}" from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/integration/.keep b/test/integration/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/mailers/.keep b/test/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/models/.keep b/test/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/models/car_test.rb b/test/models/car_test.rb new file mode 100644 index 0000000..7a94fa5 --- /dev/null +++ b/test/models/car_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class CarTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/reservation_test.rb b/test/models/reservation_test.rb new file mode 100644 index 0000000..1d04a16 --- /dev/null +++ b/test/models/reservation_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ReservationTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..5c07f49 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..0c22470 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,15 @@ +ENV["RAILS_ENV"] ||= "test" +require_relative "../config/environment" +require "rails/test_help" + +module ActiveSupport + class TestCase + # Run tests in parallel with specified workers + parallelize(workers: :number_of_processors) + + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... + end +end diff --git a/tmp/.keep b/tmp/.keep new file mode 100644 index 0000000..e69de29 diff --git a/tmp/pids/.keep b/tmp/pids/.keep new file mode 100644 index 0000000..e69de29 diff --git a/tmp/storage/.keep b/tmp/storage/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/.keep b/vendor/.keep new file mode 100644 index 0000000..e69de29 From 42c927d405b2d41eb29ba91a360838810ac4ba61 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:31:34 -0300 Subject: [PATCH 07/90] Upload the readme file --- README.md | 168 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 155 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 7db80e4..e17dfde 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,166 @@ -# README + -This README would normally document whatever steps are necessary to get the -application up and running. +

hello_rails_back_end

-Things you may want to cover: + -* Ruby version +# 📗 Table of Contents -* System dependencies +- [📗 Table of Contents](#-table-of-contents) +- [📖 hello\_rails\_back\_end ](#-hello_rails_back_end-) + - [💻 link to back end ](#-link-to-back-end-) + - [🛠 Built With ](#-built-with-) + - [Tech Stack ](#tech-stack-) + - [Key Features ](#key-features-) + - [💻 Getting Started ](#-getting-started-) + - [Prerequisites](#prerequisites) + - [Setup](#setup) + - [Install](#install) + - [Usage](#usage) + - [👥 Author ](#-author-) + - [🔭 Future Features ](#-future-features-) + - [🤝 Contributing ](#-contributing-) + - [⭐️ Show your support ](#️-show-your-support-) + - [🙏 Acknowledgments ](#-acknowledgments-) + - [❓ FAQ (OPTIONAL) ](#-faq-optional-) + - [📝 License ](#-license-) -* Configuration + -* Database creation +# 📖 hello_rails_back_end -* Database initialization +**hello_rails_back_end** The backend for this project is built using Ruby on Rails as an API. It's a simple API connected to a PostgreSQL database designed for storing greeting messages. The API has a single endpoint which randomly selects one of these messages to send to the frontend. -* How to run the test suite -* Services (job queues, cache servers, search engines, etc.) +## 💻 link to back end -* Deployment instructions -* ... +[Link to Front End](https://github.com/ClaudiaRojasSoto/hello-react-front-end) + +

(back to top)

+ +## 🛠 Built With + +### Tech Stack + +
+ Technologies + +
+
+Linters + +
+ + +### Key Features + +- [x] **Ruby on Rails and React Integration** +- [x] **API Endpoint for Random Greetings** +- [x] **Professional Documentation** +- [x] **Linting for Code Quality** +- [x] **Postgres Database** +- [x] **Git Version Control** +- [x] **Interactive User Interface** + + +

(back to top)

+ + +## 💻 Getting Started + +To get a local copy up and running, follow these steps. + +### Prerequisites + +Before you begin, make sure you have the following prerequisites installed on your system: + +- Ruby: You need Ruby to run the Ruby on Rails application. +- Bundler: Bundler is used to manage gem dependencies in your Ruby project. + +### Setup + +Clone this repository to your desired folder: + +sh
+cd my-folder
+git clone https://github.com/ClaudiaRojasSoto/hello_rails_back_end.git + +### Install + +Install this project with: + +- gem install rails +- bundle install + +### Usage + +To run the project, execute the following command: + +rails server + +## 👥 Author + +👤 **Claudia Rojas** + +- GitHub: @ClaudiaRojas +- LinkedIn: @ClaudiaRojas + +

(back to top)

+ + +## 🔭 Future Features + +- [ ] **Personalized Greetings** + + +

(back to top)

+ +## 🤝 Contributing + +Contributions, issues, and feature requests are welcome! + +Feel free to check the [issues page](https://github.com/ClaudiaRojasSoto/hello_rails_back_end/issues). + +

(back to top)

+ + +## ⭐️ Show your support + +If you like this project please feel free to send me corrections for make it better I would feel glad to read your comments. +And think If you enjoy gift me a star. + +

(back to top)

+ +## 🙏 Acknowledgments + + - Microverse for providing the opportunity to learn Git and GitHub in a collaborative environment. + - GitHub Docs for providing a wealth of information on Git and GitHub. + +

(back to top)

+ +## ❓ FAQ (OPTIONAL) + + +- **Can I use with a templeate your project?** + + - Of course I would feel honored + +- **Your project is free license?** + + - Yeah, you can use it completely + +

(back to top)

+ + +## 📝 License + +This project is licensed under the MIT License - you can click here to have more details [MIT](MIT.md). + +

(back to top)

From e997de1b5014e15f4225384883e9b84482ade22d Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:32:00 -0300 Subject: [PATCH 08/90] Add the mit license --- MIT.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 MIT.md diff --git a/MIT.md b/MIT.md new file mode 100644 index 0000000..83d214a --- /dev/null +++ b/MIT.md @@ -0,0 +1,7 @@ +Copyright 2023, Claudia Rojas + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, and to permit persons to whom the software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the software. + +THE software IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE software OR THE USE OR OTHER DEALINGS IN THE software. \ No newline at end of file From 0666e1d46d85fe20a0b1a2c5668b54f92530bb40 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:34:19 -0300 Subject: [PATCH 09/90] Upload the readme file and the mit file --- MIT.md | 2 +- README.md | 47 +++++++++++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/MIT.md b/MIT.md index 83d214a..838e94d 100644 --- a/MIT.md +++ b/MIT.md @@ -1,4 +1,4 @@ -Copyright 2023, Claudia Rojas +Copyright 2023, Claudia Rojas | Pablo Bonasera | Alexandre Medina Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, and to permit persons to whom the software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index e17dfde..7cba354 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -

hello_rails_back_end

+

final_capstone_back_end

# 📗 Table of Contents - [📗 Table of Contents](#-table-of-contents) -- [📖 hello\_rails\_back\_end ](#-hello_rails_back_end-) +- [📖 final\_capstone\_back\_end ](#-final_capstone_back_end-) - [💻 link to back end ](#-link-to-back-end-) - [🛠 Built With ](#-built-with-) - [Tech Stack ](#tech-stack-) @@ -17,7 +17,7 @@ - [Setup](#setup) - [Install](#install) - [Usage](#usage) - - [👥 Author ](#-author-) + - [👥 Authors ](#-authors-) - [🔭 Future Features ](#-future-features-) - [🤝 Contributing ](#-contributing-) - [⭐️ Show your support ](#️-show-your-support-) @@ -27,15 +27,15 @@ -# 📖 hello_rails_back_end +# 📖 final_capstone_back_end -**hello_rails_back_end** The backend for this project is built using Ruby on Rails as an API. It's a simple API connected to a PostgreSQL database designed for storing greeting messages. The API has a single endpoint which randomly selects one of these messages to send to the frontend. +**final_capstone_back_end** The back-end component of this final capstone project is developed using Ruby on Rails, configured to serve as an API. This API is designed to facilitate reservations or appointments for test drives of cars. It leverages a PostgreSQL database to manage and store reservation data. ## 💻 link to back end -[Link to Front End](https://github.com/ClaudiaRojasSoto/hello-react-front-end) +[Link to Front End](https://github.com/ClaudiaRojasSoto/final_capstone_back_end)

(back to top)

@@ -47,8 +47,6 @@ Technologies
@@ -61,13 +59,12 @@ ### Key Features -- [x] **Ruby on Rails and React Integration** -- [x] **API Endpoint for Random Greetings** +- [x] **Ruby on Rails** +- [x] **API Endpoint** - [x] **Professional Documentation** - [x] **Linting for Code Quality** - [x] **Postgres Database** - [x] **Git Version Control** -- [x] **Interactive User Interface**

(back to top)

@@ -90,7 +87,7 @@ Clone this repository to your desired folder: sh
cd my-folder
-git clone https://github.com/ClaudiaRojasSoto/hello_rails_back_end.git +git clone https://github.com/ClaudiaRojasSoto/final_capstone_back_end.git ### Install @@ -105,19 +102,30 @@ To run the project, execute the following command: rails server -## 👥 Author +## 👥 Authors 👤 **Claudia Rojas** -- GitHub: @ClaudiaRojas -- LinkedIn: @ClaudiaRojas +- GitHub: [@ClaudiaRojas](https://github.com/ClaudiaRojasSoto) +- LinkedIn: [@ClaudiaRojas](https://www.linkedin.com/in/claudia-rojas-soto/) + +👤 **Pablo Bonasera** + +- GitHub: [@PabloBona](https://github.com/PabloBona) +- LinkedIn: [Pablo Bonasera](https://www.linkedin.com/in/pablo-bonasera/) + +👤 **Alexandre Ferreira** + +- GitHub: [@AlexandreFerreira](https://github.com/alexmedinasf) +- LinkedIn: [@AlexandreFerreira](https://www.linkedin.com/in/alexmedinasf/)

(back to top)

## 🔭 Future Features -- [ ] **Personalized Greetings** +- [ ] **Implement proper user authentication from the front-end to the server** +- [ ] **Add authorizations to users**

(back to top)

@@ -126,7 +134,7 @@ rails server Contributions, issues, and feature requests are welcome! -Feel free to check the [issues page](https://github.com/ClaudiaRojasSoto/hello_rails_back_end/issues). +Feel free to check the [issues page](https://github.com/ClaudiaRojasSoto/final_capstone_back_end/issues).

(back to top)

@@ -140,8 +148,11 @@ And think If you enjoy gift me a star. ## 🙏 Acknowledgments - - Microverse for providing the opportunity to learn Git and GitHub in a collaborative environment. + - Microverse for providing the opportunity to learn in a collaborative environment. - GitHub Docs for providing a wealth of information on Git and GitHub. + - Alexandre Medina: . + - Pablo Bonasera: . + - Claudia Rojas: .

(back to top)

From 91e6dedf3f032f0895cc55be95743ff1baf5bbda Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:36:22 -0300 Subject: [PATCH 10/90] Upload the readme file --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7cba354..d98e26a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ - [📗 Table of Contents](#-table-of-contents) - [📖 final\_capstone\_back\_end ](#-final_capstone_back_end-) - - [💻 link to back end ](#-link-to-back-end-) + - [💻 link to front end ](#-link-to-front-end-) - [🛠 Built With ](#-built-with-) - [Tech Stack ](#tech-stack-) - [Key Features ](#key-features-) @@ -32,10 +32,10 @@ **final_capstone_back_end** The back-end component of this final capstone project is developed using Ruby on Rails, configured to serve as an API. This API is designed to facilitate reservations or appointments for test drives of cars. It leverages a PostgreSQL database to manage and store reservation data. -## 💻 link to back end +## 💻 link to front end -[Link to Front End](https://github.com/ClaudiaRojasSoto/final_capstone_back_end) +[Link to Front End]()

(back to top)

From 1d08a2030e88be952a07483ca897f322f63a1d5f Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Thu, 26 Oct 2023 11:58:55 -0300 Subject: [PATCH 11/90] Add images to cars tables and delete reservation columns from reservations. Upload the schema of the db --- db/migrate/20231026145529_add_image_to_cars.rb | 5 +++++ .../20231026145702_remove_available_from_reservations.rb | 5 +++++ db/schema.rb | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20231026145529_add_image_to_cars.rb create mode 100644 db/migrate/20231026145702_remove_available_from_reservations.rb diff --git a/db/migrate/20231026145529_add_image_to_cars.rb b/db/migrate/20231026145529_add_image_to_cars.rb new file mode 100644 index 0000000..ee95765 --- /dev/null +++ b/db/migrate/20231026145529_add_image_to_cars.rb @@ -0,0 +1,5 @@ +class AddImageToCars < ActiveRecord::Migration[7.1] + def change + add_column :cars, :image, :string + end +end diff --git a/db/migrate/20231026145702_remove_available_from_reservations.rb b/db/migrate/20231026145702_remove_available_from_reservations.rb new file mode 100644 index 0000000..f739e50 --- /dev/null +++ b/db/migrate/20231026145702_remove_available_from_reservations.rb @@ -0,0 +1,5 @@ +class RemoveAvailableFromReservations < ActiveRecord::Migration[7.1] + def change + remove_column :reservations, :available + end +end diff --git a/db/schema.rb b/db/schema.rb index e1fd636..ad92344 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_10_25_215755) do +ActiveRecord::Schema[7.1].define(version: 2023_10_26_145702) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -25,6 +25,7 @@ t.boolean "removed" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "image" end create_table "reservations", force: :cascade do |t| @@ -32,7 +33,6 @@ t.bigint "car_id", null: false t.datetime "start_time" t.datetime "end_time" - t.boolean "available" t.string "city" t.datetime "created_at", null: false t.datetime "updated_at", null: false From b5c45bdd2378e8a415b1ade0417b8af94143bfd2 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:13:01 -0300 Subject: [PATCH 12/90] Add the erd diagram --- README.md | 8 +++++++- diagram.jpeg | Bin 0 -> 130471 bytes 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 diagram.jpeg diff --git a/README.md b/README.md index d98e26a..969c9d0 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ - [📗 Table of Contents](#-table-of-contents) - [📖 final\_capstone\_back\_end ](#-final_capstone_back_end-) + - [🛠 ER Diagram ](#-er-diagram-) - [💻 link to front end ](#-link-to-front-end-) - [🛠 Built With ](#-built-with-) - [Tech Stack ](#tech-stack-) @@ -25,12 +26,17 @@ - [❓ FAQ (OPTIONAL) ](#-faq-optional-) - [📝 License ](#-license-) - # 📖 final_capstone_back_end **final_capstone_back_end** The back-end component of this final capstone project is developed using Ruby on Rails, configured to serve as an API. This API is designed to facilitate reservations or appointments for test drives of cars. It leverages a PostgreSQL database to manage and store reservation data. +## 🛠 ER Diagram + +![ER Diagram](diagram.jpeg) + + +

(back to top)

## 💻 link to front end diff --git a/diagram.jpeg b/diagram.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..c4ac70a18e4f4668e3e0ed9fca9095fbda2cc488 GIT binary patch literal 130471 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 literal 0 HcmV?d00001 From 470ea20e9819865c33b2617b5dff5823ab2bac51 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:22:55 -0300 Subject: [PATCH 13/90] Fix linter errors --- Gemfile | 19 ++++++++----------- app/controllers/users_controller.rb | 3 +-- app/mailers/application_mailer.rb | 4 ++-- config.ru | 2 +- .../application_cable/connection_test.rb | 2 +- test/controllers/users_controller_test.rb | 4 ++-- test/models/car_test.rb | 2 +- test/models/reservation_test.rb | 2 +- test/models/user_test.rb | 2 +- test/test_helper.rb | 6 +++--- 10 files changed, 21 insertions(+), 25 deletions(-) diff --git a/Gemfile b/Gemfile index 2a4e6d1..c3086a0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,9 +1,9 @@ -source "https://rubygems.org" +source 'https://rubygems.org' -ruby "3.2.2" +ruby '3.2.2' # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.1.1" +gem 'rails', '~> 7.1.1' gem 'rubocop', '>= 1.0', '< 2.0' @@ -11,12 +11,11 @@ gem 'rack-cors' gem 'devise' - # Use postgresql as the database for Active Record -gem "pg", "~> 1.1" +gem 'pg', '~> 1.1' # Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" +gem 'puma', '>= 5.0' # Build JSON APIs with ease [https://github.com/rails/jbuilder] # gem "jbuilder" @@ -31,10 +30,10 @@ gem "puma", ">= 5.0" # gem "bcrypt", "~> 3.1.7" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[ windows jruby ] +gem 'tzinfo-data', platforms: %i[windows jruby] # Reduces boot times through caching; required in config/boot.rb -gem "bootsnap", require: false +gem 'bootsnap', require: false # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] # gem "image_processing", "~> 1.2" @@ -44,12 +43,10 @@ gem "bootsnap", require: false 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 'debug', platforms: %i[mri windows] end group :development do # Speed up commands on slow machines / big apps [https://github.com/rails/spring] # gem "spring" - end - diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 3004a55..ed2d410 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,4 +1,3 @@ class UsersController < ApplicationController - def index - end + def index; end end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 3c34c81..286b223 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,4 @@ class ApplicationMailer < ActionMailer::Base - default from: "from@example.com" - layout "mailer" + default from: 'from@example.com' + layout 'mailer' end diff --git a/config.ru b/config.ru index 4a3c09a..ad1fbf2 100644 --- a/config.ru +++ b/config.ru @@ -1,6 +1,6 @@ # This file is used by Rack-based servers to start the application. -require_relative "config/environment" +require_relative 'config/environment' run Rails.application Rails.application.load_server diff --git a/test/channels/application_cable/connection_test.rb b/test/channels/application_cable/connection_test.rb index 6340bf9..f925925 100644 --- a/test/channels/application_cable/connection_test.rb +++ b/test/channels/application_cable/connection_test.rb @@ -1,4 +1,4 @@ -require "test_helper" +require 'test_helper' module ApplicationCable class ConnectionTest < ActionCable::Connection::TestCase diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index 4938283..ad5d6bf 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -1,7 +1,7 @@ -require "test_helper" +require 'test_helper' class UsersControllerTest < ActionDispatch::IntegrationTest - test "should get index" do + test 'should get index' do get users_index_url assert_response :success end diff --git a/test/models/car_test.rb b/test/models/car_test.rb index 7a94fa5..39bdaec 100644 --- a/test/models/car_test.rb +++ b/test/models/car_test.rb @@ -1,4 +1,4 @@ -require "test_helper" +require 'test_helper' class CarTest < ActiveSupport::TestCase # test "the truth" do diff --git a/test/models/reservation_test.rb b/test/models/reservation_test.rb index 1d04a16..391559f 100644 --- a/test/models/reservation_test.rb +++ b/test/models/reservation_test.rb @@ -1,4 +1,4 @@ -require "test_helper" +require 'test_helper' class ReservationTest < ActiveSupport::TestCase # test "the truth" do diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 5c07f49..82f61e0 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -1,4 +1,4 @@ -require "test_helper" +require 'test_helper' class UserTest < ActiveSupport::TestCase # test "the truth" do diff --git a/test/test_helper.rb b/test/test_helper.rb index 0c22470..1b7300e 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,6 +1,6 @@ -ENV["RAILS_ENV"] ||= "test" -require_relative "../config/environment" -require "rails/test_help" +ENV['RAILS_ENV'] ||= 'test' +require_relative '../config/environment' +require 'rails/test_help' module ActiveSupport class TestCase From 03fa755394ce5a2ebd2536982885c213f3377db0 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:37:56 -0300 Subject: [PATCH 14/90] Add the devise and bcr ypt gems to use authentification --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index c3086a0..ebf40f8 100644 --- a/Gemfile +++ b/Gemfile @@ -11,6 +11,8 @@ gem 'rack-cors' gem 'devise' +gem 'bcrypt', '~> 3.1', '>= 3.1.16' + # Use postgresql as the database for Active Record gem 'pg', '~> 1.1' From 191e94aea674addbe9e109f91fa6cce946a8dead Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:38:23 -0300 Subject: [PATCH 15/90] Upload the lock gemfile --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2a3f279..5c9b11a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -195,8 +195,7 @@ GEM actionpack (>= 5.2) railties (>= 5.2) rexml (3.2.6) - rubocop (1.57.1) - base64 (~> 0.1.1) + rubocop (1.57.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -207,7 +206,7 @@ GEM rubocop-ast (>= 1.28.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) + rubocop-ast (1.30.0) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -230,6 +229,7 @@ PLATFORMS x86_64-linux DEPENDENCIES + bcrypt (~> 3.1, >= 3.1.16) bootsnap debug devise From e112ee0b1b80b7c699ef7d951c1136c6d730e0b3 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:39:09 -0300 Subject: [PATCH 16/90] Delete the seeds added on seed file --- db/seeds.rb | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/db/seeds.rb b/db/seeds.rb index 4fbd6ed..354ef85 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,9 +1,28 @@ -# This file should ensure the existence of records required to run the application in every environment (production, -# development, test). The code here should be idempotent so that it can be executed at any point in every environment. -# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). -# -# Example: -# -# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| -# MovieGenre.find_or_create_by!(name: genre_name) -# end +Car.delete_all + +Car.create([ + { + id: 1, + name: "Car 1", + description: "This is a description for Car 1", + deposit: 1000, + finance_fee: 200, + option_to_purchase_fee: 300, + total_amount_payable: 1500, + duration: 12, + removed: false, + image: "image_url_1" + }, + { + id: 2, + name: "Car 2", + description: "This is a description for Car 2", + deposit: 2000, + finance_fee: 200, + option_to_purchase_fee: 300, + total_amount_payable: 1500, + duration: 12, + removed: false, + image: "image_url_2" + }, +]) \ No newline at end of file From c21fa9620677b9b0edd9e19a6c6d6fb212e5caeb Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:39:40 -0300 Subject: [PATCH 17/90] Add active storage with a migration --- ...te_active_storage_tables.active_storage.rb | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 db/migrate/20231026184727_create_active_storage_tables.active_storage.rb diff --git a/db/migrate/20231026184727_create_active_storage_tables.active_storage.rb b/db/migrate/20231026184727_create_active_storage_tables.active_storage.rb new file mode 100644 index 0000000..e4706aa --- /dev/null +++ b/db/migrate/20231026184727_create_active_storage_tables.active_storage.rb @@ -0,0 +1,57 @@ +# This migration comes from active_storage (originally 20170806125915) +class CreateActiveStorageTables < ActiveRecord::Migration[7.0] + def change + # Use Active Record's configured type for primary and foreign keys + primary_key_type, foreign_key_type = primary_and_foreign_key_types + + create_table :active_storage_blobs, id: primary_key_type do |t| + t.string :key, null: false + t.string :filename, null: false + t.string :content_type + t.text :metadata + t.string :service_name, null: false + t.bigint :byte_size, null: false + t.string :checksum + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :key ], unique: true + end + + create_table :active_storage_attachments, id: primary_key_type do |t| + t.string :name, null: false + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + t.references :blob, null: false, type: foreign_key_type + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + + create_table :active_storage_variant_records, id: primary_key_type do |t| + t.belongs_to :blob, null: false, index: false, type: foreign_key_type + t.string :variation_digest, null: false + + t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_and_foreign_key_types + config = Rails.configuration.generators + setting = config.options[config.orm][:primary_key_type] + primary_key_type = setting || :primary_key + foreign_key_type = setting || :bigint + [primary_key_type, foreign_key_type] + end +end From bc5e65fcdaf1f4c47924f312dad8ec540729a3b4 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:40:22 -0300 Subject: [PATCH 18/90] Remove devise columns by a new migration --- .../20231026205125_remove_devise_columns_from_users.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 db/migrate/20231026205125_remove_devise_columns_from_users.rb diff --git a/db/migrate/20231026205125_remove_devise_columns_from_users.rb b/db/migrate/20231026205125_remove_devise_columns_from_users.rb new file mode 100644 index 0000000..461f505 --- /dev/null +++ b/db/migrate/20231026205125_remove_devise_columns_from_users.rb @@ -0,0 +1,10 @@ +class RemoveDeviseColumnsFromUsers < ActiveRecord::Migration[7.1] + def change + remove_column :users, :email + remove_column :users, :encrypted_password + remove_column :users, :reset_password_token + remove_column :users, :reset_password_sent_at + remove_column :users, :remember_created_at + + end +end From 966961f44fe54b3d07f8346b21a21f8ad2d39259 Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:41:00 -0300 Subject: [PATCH 19/90] Add the attributes name. email and password to user --- .../20231026205913_add_name_email_and_password_to_users.rb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 db/migrate/20231026205913_add_name_email_and_password_to_users.rb diff --git a/db/migrate/20231026205913_add_name_email_and_password_to_users.rb b/db/migrate/20231026205913_add_name_email_and_password_to_users.rb new file mode 100644 index 0000000..8824e3f --- /dev/null +++ b/db/migrate/20231026205913_add_name_email_and_password_to_users.rb @@ -0,0 +1,7 @@ +class AddNameEmailAndPasswordToUsers < ActiveRecord::Migration[7.1] + def change + add_column :users, :name, :string + add_column :users, :email, :string + add_column :users, :password, :string + end +end From 24e18bfeaf4e085fb6a0b5de142a05765280d30d Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:42:10 -0300 Subject: [PATCH 20/90] Rename the password column to use the bcrypt gem --- db/migrate/20231026225531_rename_password_column_in_users.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20231026225531_rename_password_column_in_users.rb diff --git a/db/migrate/20231026225531_rename_password_column_in_users.rb b/db/migrate/20231026225531_rename_password_column_in_users.rb new file mode 100644 index 0000000..3c3528e --- /dev/null +++ b/db/migrate/20231026225531_rename_password_column_in_users.rb @@ -0,0 +1,5 @@ +class RenamePasswordColumnInUsers < ActiveRecord::Migration[7.1] + def change + rename_column :users, :password, :password_digest + end +end From befc23cb5fe2dc4a59034c63c05e87539d82e55e Mon Sep 17 00:00:00 2001 From: "Claudia P. R. Soto" <97201255+ClaudiaRojasSoto@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:42:34 -0300 Subject: [PATCH 21/90] Add images to use the active storage --- public/images/car-4.png | Bin 0 -> 1136660 bytes public/images/car-5.png | Bin 0 -> 529735 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/images/car-4.png create mode 100644 public/images/car-5.png diff --git a/public/images/car-4.png b/public/images/car-4.png new file mode 100644 index 0000000000000000000000000000000000000000..6dce6c4c1983939cf30154716095af243d435fa8 GIT binary patch literal 1136660 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�`H%)2)l>cR^97zHAeL*AVW% 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