diff --git a/.annotaterb.yml b/.annotaterb.yml new file mode 100644 index 0000000..6de30ac --- /dev/null +++ b/.annotaterb.yml @@ -0,0 +1,58 @@ +--- +:position: bottom +:position_in_additional_file_patterns: bottom +:position_in_class: bottom +:position_in_factory: bottom +:position_in_fixture: bottom +:position_in_routes: bottom +:position_in_serializer: bottom +:position_in_test: bottom +:classified_sort: true +:exclude_controllers: true +:exclude_factories: false +:exclude_fixtures: false +:exclude_helpers: true +:exclude_scaffolds: true +:exclude_serializers: false +:exclude_sti_subclasses: false +:exclude_tests: false +:force: false +:format_markdown: false +:format_rdoc: false +:format_yard: false +:frozen: false +:ignore_model_sub_dir: false +:ignore_unknown_models: false +:include_version: false +:show_check_constraints: false +:show_complete_foreign_keys: false +:show_foreign_keys: true +:show_indexes: true +:simple_indexes: false +:sort: false +:timestamp: false +:trace: false +:with_comment: true +:with_column_comments: true +:with_table_comments: true +:active_admin: false +:command: +:debug: false +:hide_default_column_types: 'json,jsonb,hstore' +:hide_limit_column_types: 'integer,bigint,boolean' +:ignore_columns: +:ignore_routes: +:models: true +:routes: false +:skip_on_db_migrate: false +:target_action: :do_annotations +:wrapper: +:wrapper_close: +:wrapper_open: +:classes_default_to_s: [] +:additional_file_patterns: [] +:model_dir: + - app/models +:require: [] +:root_dir: + - '' diff --git a/.rubocop.todo.yml b/.rubocop.todo.yml deleted file mode 100644 index e69de29..0000000 diff --git a/.rubocop.yml b/.rubocop.yml index 0926fdd..38fcf7d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,10 +1,20 @@ require: rubocop-rails -inherit_from: .rubocop.todo.yml +inherit_gem: + rubocop-rails-omakase: rubocop.yml + +# Your own specialized rules go here AllCops: NewCops: enable SuggestExtensions: false + Exclude: + - db/schema.rb + - bin/**/* + - tmp/**/* + - vendor/**/* + - log/**/* + - config/initializers/* Layout/LineLength: Max: 160 @@ -14,6 +24,10 @@ Layout/LineLength: Exclude: - db/migrate/* +Lint/AssignmentInCondition: + Exclude: + - db/migrate/20250131123310_add_service_name_to_active_storage_blobs.active_storage.rb + Metrics/AbcSize: Max: 19 Exclude: @@ -54,6 +68,10 @@ Rails/Output: Rails/ScopeArgs: Enabled: false +Rails/SkipsModelValidations: + Exclude: + - db/migrate/20250131123310_add_service_name_to_active_storage_blobs.active_storage.rb + Rails/UnknownEnv: Environments: - development diff --git a/Gemfile b/Gemfile index 8a7d438..833f56d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,45 +1,44 @@ # frozen_string_literal: true -source 'https://rubygems.org' +source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby file: '.ruby-version' +ruby file: ".ruby-version" -gem 'rails', '~> 7.2' +gem "rails", "~> 8.0.1" -gem 'aws-sdk-s3', '~> 1.122' -gem 'blueprinter', '~> 1.0', '>= 1.0.2' -gem 'bootsnap', '~> 1.18', '>= 1.18.3', require: false -gem 'devise', '~> 4.9', '>= 4.9.4' -gem 'devise-jwt', '~> 0.11.0' -gem 'dry-initializer', '~> 3.1', '>= 3.1.1' -gem 'pg', '~> 1.5', '>= 1.5.6' -gem 'puma', '~> 6.4', '>= 6.4.2' -gem 'rack-cors', '~> 2.0', '>= 2.0.2' -gem 'redis', '~> 5.2' -gem 'ruby-vips', '~> 2.2', '>= 2.2.1' -gem 'sidekiq', '~> 7.3' -gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby] -gem 'warped', '~> 1.0.0' +gem "aws-sdk-s3", "~> 1.122" +gem "blueprinter", "~> 1.0", ">= 1.0.2" +gem "bootsnap", "~> 1.18", ">= 1.18.3", require: false +gem "devise", "~> 4.9", ">= 4.9.4" +gem "devise-jwt", "~> 0.11.0" +gem "dry-initializer", "~> 3.1", ">= 3.1.1" +gem "pg", "~> 1.5", ">= 1.5.6" +gem "puma", "~> 6.4", ">= 6.4.2" +gem "rack-cors", "~> 2.0", ">= 2.0.2" +gem "redis", "~> 5.2" +gem "ruby-vips", "~> 2.2", ">= 2.2.1" +gem "sidekiq", "~> 7.3" +gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] +gem "warped", "~> 1.0.1" group :development, :test do - gem 'bullet', '~> 7.1', '>= 7.1.6' - gem 'debug', '~> 1.9', '>= 1.9.2', platforms: %i[mri mingw x64_mingw] - gem 'dotenv-rails', '~> 3.1', '>= 3.1.2' - gem 'factory_bot_rails', '~> 6.4', '>= 6.4.3' - gem 'faker', '~> 3.2', '>= 3.2.3' - gem 'rspec-rails', '~> 6.1', '>= 6.1.3' - gem 'rubocop', '~> 1.64', '>= 1.64.1', require: false - gem 'rubocop-rails', '~> 2.25', '>= 2.25.1', require: false + gem "bullet", "~> 8.0" + gem "debug", "~> 1.9", ">= 1.9.2", platforms: %i[mri mingw x64_mingw] + gem "dotenv-rails", "~> 3.1", ">= 3.1.2" + gem "factory_bot_rails", "~> 6.4", ">= 6.4.3" + gem "faker", "~> 3.2", ">= 3.2.3" + gem "rspec-rails", "~> 6.1", ">= 6.1.3" end group :development do - gem 'annotate', '~> 3.2' - gem 'dockerfile-rails', '~> 1.6', '>= 1.6.17' - gem 'letter_opener', '~> 1.10' + gem "annotaterb", "~> 4.13" + gem "dockerfile-rails", "~> 1.6", ">= 1.6.17" + gem "letter_opener", "~> 1.10" + gem "rubocop-rails-omakase", require: false end group :test do - gem 'shoulda-matchers', '~> 6.2' - gem 'simplecov', '~> 0.22.0', require: false + gem "shoulda-matchers", "~> 6.2" + gem "simplecov", "~> 0.22.0", require: false end diff --git a/Gemfile.lock b/Gemfile.lock index 9e39120..e5bba55 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,67 +1,67 @@ GEM remote: https://rubygems.org/ specs: - actioncable (7.2.0) - actionpack (= 7.2.0) - activesupport (= 7.2.0) + actioncable (8.0.1) + actionpack (= 8.0.1) + activesupport (= 8.0.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.2.0) - actionpack (= 7.2.0) - activejob (= 7.2.0) - activerecord (= 7.2.0) - activestorage (= 7.2.0) - activesupport (= 7.2.0) + actionmailbox (8.0.1) + actionpack (= 8.0.1) + activejob (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) mail (>= 2.8.0) - actionmailer (7.2.0) - actionpack (= 7.2.0) - actionview (= 7.2.0) - activejob (= 7.2.0) - activesupport (= 7.2.0) + actionmailer (8.0.1) + actionpack (= 8.0.1) + actionview (= 8.0.1) + activejob (= 8.0.1) + activesupport (= 8.0.1) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.2.0) - actionview (= 7.2.0) - activesupport (= 7.2.0) + actionpack (8.0.1) + actionview (= 8.0.1) + activesupport (= 8.0.1) nokogiri (>= 1.8.5) - racc - rack (>= 2.2.4, < 3.2) + rack (>= 2.2.4) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (7.2.0) - actionpack (= 7.2.0) - activerecord (= 7.2.0) - activestorage (= 7.2.0) - activesupport (= 7.2.0) + actiontext (8.0.1) + actionpack (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.2.0) - activesupport (= 7.2.0) + actionview (8.0.1) + activesupport (= 8.0.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.2.0) - activesupport (= 7.2.0) + activejob (8.0.1) + activesupport (= 8.0.1) globalid (>= 0.3.6) - activemodel (7.2.0) - activesupport (= 7.2.0) - activerecord (7.2.0) - activemodel (= 7.2.0) - activesupport (= 7.2.0) + activemodel (8.0.1) + activesupport (= 8.0.1) + activerecord (8.0.1) + activemodel (= 8.0.1) + activesupport (= 8.0.1) timeout (>= 0.4.0) - activestorage (7.2.0) - actionpack (= 7.2.0) - activejob (= 7.2.0) - activerecord (= 7.2.0) - activesupport (= 7.2.0) + activestorage (8.0.1) + actionpack (= 8.0.1) + activejob (= 8.0.1) + activerecord (= 8.0.1) + activesupport (= 8.0.1) marcel (~> 1.0) - activesupport (7.2.0) + activesupport (8.0.1) base64 + benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) @@ -71,11 +71,10 @@ GEM minitest (>= 5.1) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) - annotate (3.2.0) - activerecord (>= 3.2, < 8.0) - rake (>= 10.4, < 14.0) + annotaterb (4.13.0) ast (2.4.2) aws-eventstream (1.3.0) aws-partitions (1.963.0) @@ -95,12 +94,13 @@ GEM aws-eventstream (~> 1, >= 1.0.2) base64 (0.2.0) bcrypt (3.1.20) + benchmark (0.4.0) bigdecimal (3.1.8) blueprinter (1.1.0) bootsnap (1.18.4) msgpack (~> 1.2) builder (3.3.0) - bullet (7.2.0) + bullet (8.0.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) childprocess (5.1.0) @@ -108,7 +108,7 @@ GEM concurrent-ruby (1.3.4) connection_pool (2.4.1) crass (1.0.6) - date (3.3.4) + date (3.4.1) debug (1.9.2) irb (~> 1.10) reline (>= 0.3.8) @@ -167,10 +167,10 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) jmespath (1.6.2) - json (2.7.2) + json (2.9.1) jwt (2.8.2) base64 - language_server-protocol (3.17.0.3) + language_server-protocol (3.17.0.4) launchy (3.0.1) addressable (~> 2.8) childprocess (~> 5.0) @@ -189,7 +189,7 @@ GEM mini_mime (1.1.5) minitest (5.25.0) msgpack (1.7.2) - net-imap (0.4.14) + net-imap (0.5.5) date net-protocol net-pop (0.1.2) @@ -212,8 +212,8 @@ GEM nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.26.2) - parser (3.3.4.2) + parallel (1.26.3) + parser (3.3.7.1) ast (~> 2.4.1) racc pg (1.5.7) @@ -233,20 +233,20 @@ GEM rackup (2.1.0) rack (>= 3) webrick (~> 1.8) - rails (7.2.0) - actioncable (= 7.2.0) - actionmailbox (= 7.2.0) - actionmailer (= 7.2.0) - actionpack (= 7.2.0) - actiontext (= 7.2.0) - actionview (= 7.2.0) - activejob (= 7.2.0) - activemodel (= 7.2.0) - activerecord (= 7.2.0) - activestorage (= 7.2.0) - activesupport (= 7.2.0) + rails (8.0.1) + actioncable (= 8.0.1) + actionmailbox (= 8.0.1) + actionmailer (= 8.0.1) + actionpack (= 8.0.1) + actiontext (= 8.0.1) + actionview (= 8.0.1) + activejob (= 8.0.1) + activemodel (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) bundler (>= 1.15.0) - railties (= 7.2.0) + railties (= 8.0.1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -254,9 +254,9 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.2.0) - actionpack (= 7.2.0) - activesupport (= 7.2.0) + railties (8.0.1) + actionpack (= 8.0.1) + activesupport (= 8.0.1) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -270,14 +270,12 @@ GEM redis-client (>= 0.22.0) redis-client (0.22.2) connection_pool - regexp_parser (2.9.2) + regexp_parser (2.10.0) reline (0.5.9) io-console (~> 0.5) responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.3.5) - strscan rspec-core (3.13.0) rspec-support (~> 3.13.0) rspec-expectations (3.13.1) @@ -295,24 +293,34 @@ GEM rspec-mocks (~> 3.13) rspec-support (~> 3.13) rspec-support (3.13.1) - rubocop (1.65.1) + rubocop (1.71.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 2.4, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.31.1, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.38.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.0) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.38.0) parser (>= 3.3.1.0) - rubocop-rails (2.25.1) + rubocop-minitest (0.36.0) + rubocop (>= 1.61, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-performance (1.23.1) + rubocop (>= 1.48.1, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails (2.29.1) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 1.33.0, < 2.0) + rubocop (>= 1.52.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails-omakase (1.0.0) + rubocop + rubocop-minitest + rubocop-performance + rubocop-rails ruby-progressbar (1.13.0) ruby-vips (2.2.2) ffi (~> 1.12) @@ -333,13 +341,15 @@ GEM simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) stringio (3.1.1) - strscan (3.1.0) thor (1.3.1) - timeout (0.4.1) + timeout (0.4.3) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.5.0) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) uniform_notifier (1.16.0) + uri (1.0.2) useragent (0.16.10) warden (1.2.9) rack (>= 2.0.9) @@ -348,11 +358,12 @@ GEM dry-configurable (>= 0.13, < 2) jwt (~> 2.1) warden (~> 1.2) - warped (1.0.0) - rails (>= 7.1.0, <= 8.0) + warped (1.0.1) + rails (>= 7.1.0) zeitwerk (>= 2.4) webrick (1.8.1) - websocket-driver (0.7.6) + websocket-driver (0.7.7) + base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) zeitwerk (2.6.17) @@ -374,11 +385,11 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES - annotate (~> 3.2) + annotaterb (~> 4.13) aws-sdk-s3 (~> 1.122) blueprinter (~> 1.0, >= 1.0.2) bootsnap (~> 1.18, >= 1.18.3) - bullet (~> 7.1, >= 7.1.6) + bullet (~> 8.0) debug (~> 1.9, >= 1.9.2) devise (~> 4.9, >= 4.9.4) devise-jwt (~> 0.11.0) @@ -391,17 +402,16 @@ DEPENDENCIES pg (~> 1.5, >= 1.5.6) puma (~> 6.4, >= 6.4.2) rack-cors (~> 2.0, >= 2.0.2) - rails (~> 7.2) + rails (~> 8.0.1) redis (~> 5.2) rspec-rails (~> 6.1, >= 6.1.3) - rubocop (~> 1.64, >= 1.64.1) - rubocop-rails (~> 2.25, >= 2.25.1) + rubocop-rails-omakase ruby-vips (~> 2.2, >= 2.2.1) shoulda-matchers (~> 6.2) sidekiq (~> 7.3) simplecov (~> 0.22.0) tzinfo-data - warped (~> 1.0.0) + warped (~> 1.0.1) RUBY VERSION ruby 3.3.6p108 diff --git a/app/controllers/api/application_controller.rb b/app/controllers/api/application_controller.rb index f7416ce..bd785c7 100644 --- a/app/controllers/api/application_controller.rb +++ b/app/controllers/api/application_controller.rb @@ -29,7 +29,7 @@ def render_record_invalid(exception) def render_parameter_missing(exception) Rails.logger.info { exception } - render json: { error: 'A required parameter is missing' }, status: :unprocessable_entity + render json: { error: "A required parameter is missing" }, status: :unprocessable_entity end def render_bad_request(exception) diff --git a/app/controllers/api/v1/users/sessions_controller.rb b/app/controllers/api/v1/users/sessions_controller.rb index e6a2c98..b4dab92 100644 --- a/app/controllers/api/v1/users/sessions_controller.rb +++ b/app/controllers/api/v1/users/sessions_controller.rb @@ -23,7 +23,7 @@ def log_out_success end def log_out_failure - render json: { error: 'You need to sign in or sign up before continuing.' }, status: :unauthorized + render json: { error: "You need to sign in or sign up before continuing." }, status: :unauthorized end end end diff --git a/app/controllers/concerns/fake_session.rb b/app/controllers/concerns/fake_session.rb index e344f82..47b0dd2 100644 --- a/app/controllers/concerns/fake_session.rb +++ b/app/controllers/concerns/fake_session.rb @@ -20,7 +20,7 @@ def enabled? private def set_fake_rack_session_for_devise - request.env['rack.session'] ||= FakeRackSession.new + request.env["rack.session"] ||= FakeRackSession.new end end end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 3bc2f87..b02299d 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class ApplicationMailer < ActionMailer::Base - default from: ENV.fetch('MAILER_SENDER', 'info@rails-api.com') - layout 'mailer' + default from: ENV.fetch("MAILER_SENDER", "info@rails-api.com") + layout "mailer" end diff --git a/app/queries/application_query.rb b/app/queries/application_query.rb index 60f2048..7f2e3a0 100644 --- a/app/queries/application_query.rb +++ b/app/queries/application_query.rb @@ -45,7 +45,7 @@ class << self attr_writer :query_model_name def query_model_name - @query_model_name ||= name.sub(/::[^:]+$/, '') + @query_model_name ||= name.sub(/::[^:]+$/, "") end def query_model diff --git a/config/application.rb b/config/application.rb index 8e4946d..3625d63 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,22 +1,22 @@ # frozen_string_literal: true -require_relative 'boot' +require_relative "boot" -require 'rails' +require "rails" # Pick the frameworks you want: -require 'active_model/railtie' -require 'active_job/railtie' -require 'active_record/railtie' -require 'active_storage/engine' -require 'action_controller/railtie' -require 'action_mailer/railtie' -require 'action_mailbox/engine' -require 'action_text/engine' -require 'action_view/railtie' -require 'action_cable/engine' +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "active_storage/engine" +require "action_controller/railtie" +require "action_mailer/railtie" +require "action_mailbox/engine" +require "action_text/engine" +require "action_view/railtie" +require "action_cable/engine" # require "rails/test_unit/railtie" -require_relative '../lib/middlewares/silence_request' +require_relative "../lib/middlewares/silence_request" # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. @@ -25,7 +25,7 @@ module RailsApi class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.2 + config.load_defaults 8.0 # 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. @@ -54,7 +54,7 @@ class Application < Rails::Application config.middleware.insert_after(ActionDispatch::Cookies, ActionDispatch::Session::CookieStore) # Silence requests made to the /up (healthcheck) path - config.middleware.insert_before Rails::Rack::Logger, SilenceRequest, path: '/up' + config.middleware.insert_before Rails::Rack::Logger, SilenceRequest, path: "/up" config.require_master_key = false end diff --git a/config/boot.rb b/config/boot.rb index c04863f..aef6d03 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) +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. +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/environment.rb b/config/environment.rb index d5abe55..7df99e8 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Load the Rails application. -require_relative 'application' +require_relative "application" # Initialize the Rails application. Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb index a849886..64d3d53 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'active_support/core_ext/integer/time' +require "active_support/core_ext/integer/time" Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -28,9 +28,9 @@ # Enable/disable caching. By default caching is disabled. # Run rails dev:cache to toggle caching. - if Rails.root.join('tmp/caching-dev.txt').exist? + 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}" } + config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{2.days.to_i}" } else config.action_controller.perform_caching = false @@ -51,7 +51,7 @@ config.action_mailer.delivery_method = :letter_opener config.action_mailer.perform_deliveries = true - config.action_mailer.default_url_options = { host: ENV.fetch('SERVER_HOST', 'localhost'), port: 3000 } + config.action_mailer.default_url_options = { host: ENV.fetch("SERVER_HOST", "localhost"), port: 3000 } # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log diff --git a/config/environments/production.rb b/config/environments/production.rb index 9e2f05a..7fedbef 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'active_support/core_ext/integer/time' +require "active_support/core_ext/integer/time" Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -22,7 +22,7 @@ config.require_master_key = false # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. - config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" @@ -50,11 +50,11 @@ # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } # Prepend all log lines with the following tags. - config.log_tags = [:request_id] + config.log_tags = [ :request_id ] # Use a different cache store in production. config.cache_store = :redis_cache_store, { - url: ENV.fetch('REDIS_URL', nil), + url: ENV.fetch("REDIS_URL", nil), ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } } @@ -80,7 +80,7 @@ # "info" includes 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') + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") # Log to STDOUT by default config.logger = ActiveSupport::Logger.new($stdout) diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 3196b29..fc772c4 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require File.expand_path('production.rb', __dir__) +require File.expand_path("production.rb", __dir__) Rails.application.configure do - config.server_timing = ENV.fetch('SERVER_TIMING', nil).present? - config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'debug') + config.server_timing = ENV.fetch("SERVER_TIMING", nil).present? + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "debug") end diff --git a/config/environments/test.rb b/config/environments/test.rb index b5ea195..e690a96 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'active_support/core_ext/integer/time' +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 @@ -27,11 +27,11 @@ # 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? + 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}" } + 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 @@ -58,7 +58,7 @@ # Unlike controllers, the mailer instance doesn't have any context about the # incoming request so you'll need to provide the :host parameter yourself. - config.action_mailer.default_url_options = { host: ENV.fetch('SERVER_HOST', 'localhost'), port: 3000 } + config.action_mailer.default_url_options = { host: ENV.fetch("SERVER_HOST", "localhost"), port: 3000 } # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr diff --git a/config/puma.rb b/config/puma.rb index 259b180..6d6f5b5 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -22,14 +22,14 @@ # Any libraries that use a connection pool or another resource pool should # be configured to provide at least as many connections as the number of # threads. This includes Active Record's `pool` parameter in `database.yml`. -threads_count = ENV.fetch('RAILS_MAX_THREADS', 3) +threads_count = ENV.fetch("RAILS_MAX_THREADS", 3) threads threads_count, threads_count # Specifies the `port` that Puma will listen on to receive requests; default is 3000. -port ENV.fetch('PORT', 3000) +port ENV.fetch("PORT", 3000) # Allow puma to be restarted by `bin/rails restart` command. plugin :tmp_restart # Only use a pidfile when requested -pidfile ENV['PIDFILE'] if ENV['PIDFILE'] +pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/config/routes.rb b/config/routes.rb index d34e308..77f51c2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true Rails.application.routes.draw do - get 'up' => 'rails/health#show', as: :rails_health_check + get "up" => "rails/health#show", as: :rails_health_check defaults format: :html do - mount Sidekiq::Web => '/sidekiq' + mount Sidekiq::Web => "/sidekiq" # Uncomment when using AdminUser devise model for authenticated admin panels # devise_for :admin_users, only: %i[sessions password], controllers: { @@ -14,11 +14,11 @@ # root to: '/admin' end - devise_for :users, path: 'api/v1/users', defaults: { format: :json }, controllers: { - confirmations: 'api/v1/users/confirmations', - sessions: 'api/v1/users/sessions', - registrations: 'api/v1/users/registrations', - passwords: 'api/v1/users/passwords' + devise_for :users, path: "api/v1/users", defaults: { format: :json }, controllers: { + confirmations: "api/v1/users/confirmations", + sessions: "api/v1/users/sessions", + registrations: "api/v1/users/registrations", + passwords: "api/v1/users/passwords" } namespace :api, defaults: { format: :json } do diff --git a/db/migrate/20231124152822_create_active_storage_tables.active_storage.rb b/db/migrate/20231124152822_create_active_storage_tables.active_storage.rb index 8e9b357..9274030 100644 --- a/db/migrate/20231124152822_create_active_storage_tables.active_storage.rb +++ b/db/migrate/20231124152822_create_active_storage_tables.active_storage.rb @@ -21,7 +21,7 @@ def change t.datetime :created_at, null: false end - t.index [:key], unique: true + t.index [ :key ], unique: true end create_table :active_storage_attachments, id: primary_key_type do |t| @@ -55,6 +55,6 @@ def primary_and_foreign_key_types 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] + [ primary_key_type, foreign_key_type ] end end diff --git a/db/migrate/20250131123310_add_service_name_to_active_storage_blobs.active_storage.rb b/db/migrate/20250131123310_add_service_name_to_active_storage_blobs.active_storage.rb new file mode 100644 index 0000000..95183b0 --- /dev/null +++ b/db/migrate/20250131123310_add_service_name_to_active_storage_blobs.active_storage.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# This migration comes from active_storage (originally 20190112182829) +class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0] + def up + return unless table_exists?(:active_storage_blobs) + + return if column_exists?(:active_storage_blobs, :service_name) + + add_column :active_storage_blobs, :service_name, :string + + if configured_service = ActiveStorage::Blob.service.name + ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) + end + + change_column :active_storage_blobs, :service_name, :string, null: false + end + + def down + return unless table_exists?(:active_storage_blobs) + + remove_column :active_storage_blobs, :service_name + end +end diff --git a/db/migrate/20250131123311_create_active_storage_variant_records.active_storage.rb b/db/migrate/20250131123311_create_active_storage_variant_records.active_storage.rb new file mode 100644 index 0000000..ca0e862 --- /dev/null +++ b/db/migrate/20250131123311_create_active_storage_variant_records.active_storage.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +# This migration comes from active_storage (originally 20191206030411) +class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + # Use Active Record's configured type for primary key + create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t| + t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type + t.string :variation_digest, null: false + + t.index %i[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_key_type + config = Rails.configuration.generators + config.options[config.orm][:primary_key_type] || :primary_key + end + + def blobs_primary_key_type + pkey_name = connection.primary_key(:active_storage_blobs) + pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name } + pkey_column.bigint? ? :bigint : pkey_column.type + end +end diff --git a/db/migrate/20250131123312_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb b/db/migrate/20250131123312_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb new file mode 100644 index 0000000..6f31822 --- /dev/null +++ b/db/migrate/20250131123312_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# This migration comes from active_storage (originally 20211119233751) +class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + change_column_null(:active_storage_blobs, :checksum, true) + end +end diff --git a/db/schema.rb b/db/schema.rb index 1e8f2ec..728dde4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,9 +10,9 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2023_11_24_152822) do +ActiveRecord::Schema[8.0].define(version: 2025_01_31_123312) do # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" + enable_extension "pg_catalog.plpgsql" create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false @@ -29,10 +29,10 @@ 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" t.datetime "created_at", null: false + t.string "service_name", null: false t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end diff --git a/lib/generators/address/address_generator.rb b/lib/generators/address/address_generator.rb index 0cbb931..8cde903 100644 --- a/lib/generators/address/address_generator.rb +++ b/lib/generators/address/address_generator.rb @@ -4,43 +4,43 @@ class AddressGenerator < Rails::Generators::Base include Rails::Generators::Migration # source_root is used to tell Rails where to look for the template files - source_root File.expand_path('templates', __dir__) + source_root File.expand_path("templates", __dir__) def file_name - 'address' + "address" end def self.next_migration_number(_path) - Time.current.strftime('%Y%m%d%H%M%S') + Time.current.strftime("%Y%m%d%H%M%S") end def copy_address_file - template 'address.rb.tt', File.join('app/models', "#{file_name}.rb") + template "address.rb.tt", File.join("app/models", "#{file_name}.rb") end def copy_address_factory_file - template 'addresses.rb.tt', File.join('spec/factories', "#{file_name.pluralize}.rb") + template "addresses.rb.tt", File.join("spec/factories", "#{file_name.pluralize}.rb") end def copy_address_spec_file - template 'address_spec.rb.tt', File.join('spec/models', "#{file_name}_spec.rb") + template "address_spec.rb.tt", File.join("spec/models", "#{file_name}_spec.rb") end def copy_serializer_file - template 'address_serializer.rb.tt', File.join('app/serializers', "#{file_name}_serializer.rb") + template "address_serializer.rb.tt", File.join("app/serializers", "#{file_name}_serializer.rb") end def create_migration_file - copy_migration('create_addresses') + copy_migration("create_addresses") end private def copy_migration(filename) - if self.class.migration_exists?('db/migrate', filename) - say_status('skipped', "Migration #{filename}.rb already exists") + if self.class.migration_exists?("db/migrate", filename) + say_status("skipped", "Migration #{filename}.rb already exists") else - migration_template "#{filename}.rb.tt", File.join('db/migrate', "#{filename}.rb") + migration_template "#{filename}.rb.tt", File.join("db/migrate", "#{filename}.rb") end end end diff --git a/lib/generators/heroku/heroku_generator.rb b/lib/generators/heroku/heroku_generator.rb index b6ab3fb..a4b3d6b 100644 --- a/lib/generators/heroku/heroku_generator.rb +++ b/lib/generators/heroku/heroku_generator.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true class HerokuGenerator < Rails::Generators::Base - desc 'Creates Heroku files for deployment' - class_option :app_name, type: :string, default: nil, desc: 'Name of the Heroku app' + desc "Creates Heroku files for deployment" + class_option :app_name, type: :string, default: nil, desc: "Name of the Heroku app" - source_root File.expand_path('templates', __dir__) + source_root File.expand_path("templates", __dir__) def copy_files @app_name = options[:app_name] - copy_file 'Procfile' - copy_file 'Aptfile' - copy_file 'release.sh' - template 'app.json.erb', 'app.json' + copy_file "Procfile" + copy_file "Aptfile" + copy_file "release.sh" + template "app.json.erb", "app.json" end end diff --git a/lib/generators/sentry/sentry_generator.rb b/lib/generators/sentry/sentry_generator.rb index 1eb042c..f80d6fb 100644 --- a/lib/generators/sentry/sentry_generator.rb +++ b/lib/generators/sentry/sentry_generator.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true class SentryGenerator < Rails::Generators::Base - source_root File.expand_path('templates', __dir__) + source_root File.expand_path("templates", __dir__) def add_sentry_gem - gem 'stackprof' - gem 'sentry-ruby' - gem 'sentry-rails' - run 'bundle' + gem "stackprof" + gem "sentry-ruby" + gem "sentry-rails" + run "bundle" end def create_sentry_initializer - template 'sentry.rb', 'config/initializers/sentry.rb' + template "sentry.rb", "config/initializers/sentry.rb" end def create_sentry_environment_variables - append_to_file '.env.sample', "SENTRY_DSN=sentry_dsn\n" + append_to_file ".env.sample", "SENTRY_DSN=sentry_dsn\n" end end diff --git a/lib/generators/sentry/templates/sentry.rb b/lib/generators/sentry/templates/sentry.rb index 552e947..c6e300e 100644 --- a/lib/generators/sentry/templates/sentry.rb +++ b/lib/generators/sentry/templates/sentry.rb @@ -4,11 +4,11 @@ Sentry.init do |config| config.enabled_environments = %w[production staging] - config.dsn = ENV.fetch('SENTRY_DSN', nil) + config.dsn = ENV.fetch("SENTRY_DSN", nil) config.environment = Rails.env - kamal_release_sha = ENV.fetch('KAMAL_VERSION', nil) + kamal_release_sha = ENV.fetch("KAMAL_VERSION", nil) config.release = kamal_release_sha if kamal_release_sha.present? diff --git a/lib/middlewares/silence_request.rb b/lib/middlewares/silence_request.rb index e485191..752b06f 100644 --- a/lib/middlewares/silence_request.rb +++ b/lib/middlewares/silence_request.rb @@ -20,7 +20,7 @@ def initialize(app, path:) end def call(env) - if env['PATH_INFO'] == @path + if env["PATH_INFO"] == @path Rails.logger.silence { @app.call(env) } else @app.call(env) diff --git a/lib/tasks/annotate_rb.rake b/lib/tasks/annotate_rb.rake new file mode 100644 index 0000000..611cfe9 --- /dev/null +++ b/lib/tasks/annotate_rb.rake @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# This rake task was added by annotate_rb gem. + +# Can set `ANNOTATERB_SKIP_ON_DB_TASKS` to be anything to skip this +if Rails.env.development? && ENV["ANNOTATERB_SKIP_ON_DB_TASKS"].nil? + require "annotate_rb" + + AnnotateRb::Core.load_rake_tasks +end diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake deleted file mode 100644 index 492ce91..0000000 --- a/lib/tasks/auto_annotate_models.rake +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -# NOTE: only doing this in development as some production environments (Heroku) -# NOTE: are sensitive to local FS writes, and besides -- it's just not proper -# NOTE: to have a dev-mode tool do its thing in production. -if Rails.env.development? - require 'annotate' - task set_annotation_options: :environment do - # You can override any of these by setting an environment variable of the - # same name. - Annotate.set_defaults( - 'active_admin' => 'false', - 'additional_file_patterns' => [], - 'routes' => 'false', - 'models' => 'true', - 'position_in_routes' => 'bottom', - 'position_in_class' => 'bottom', - 'position_in_test' => 'bottom', - 'position_in_fixture' => 'bottom', - 'position_in_factory' => 'bottom', - 'position_in_serializer' => 'bottom', - 'show_foreign_keys' => 'true', - 'show_complete_foreign_keys' => 'false', - 'show_indexes' => 'true', - 'simple_indexes' => 'false', - 'model_dir' => 'app/models', - 'root_dir' => '', - 'include_version' => 'false', - 'require' => '', - 'exclude_tests' => 'false', - 'exclude_fixtures' => 'false', - 'exclude_factories' => 'false', - 'exclude_serializers' => 'false', - 'exclude_scaffolds' => 'true', - 'exclude_controllers' => 'true', - 'exclude_helpers' => 'true', - 'exclude_sti_subclasses' => 'false', - 'ignore_model_sub_dir' => 'false', - 'ignore_columns' => nil, - 'ignore_routes' => nil, - 'ignore_unknown_models' => 'false', - 'hide_limit_column_types' => 'integer,bigint,boolean', - 'hide_default_column_types' => 'json,jsonb,hstore', - 'skip_on_db_migrate' => 'false', - 'format_bare' => 'true', - 'format_rdoc' => 'false', - 'format_yard' => 'false', - 'format_markdown' => 'false', - 'sort' => 'false', - 'force' => 'false', - 'frozen' => 'false', - 'classified_sort' => 'true', - 'trace' => 'false', - 'wrapper_open' => nil, - 'wrapper_close' => nil, - 'with_comment' => 'true' - ) - end - - Annotate.load_tasks -end diff --git a/spec/requests/users/confirmations/create_spec.rb b/spec/requests/users/confirmations/create_spec.rb index 4a4ddf4..756ed66 100644 --- a/spec/requests/users/confirmations/create_spec.rb +++ b/spec/requests/users/confirmations/create_spec.rb @@ -34,7 +34,7 @@ it 'returns an error message' do subject - expect(json[:errors][:email]).to eq(['not found']) + expect(json[:errors][:email]).to eq([ 'not found' ]) end it 'does not send an email' do diff --git a/spec/requests/users/confirmations/show_spec.rb b/spec/requests/users/confirmations/show_spec.rb index 94a5d24..455bc79 100644 --- a/spec/requests/users/confirmations/show_spec.rb +++ b/spec/requests/users/confirmations/show_spec.rb @@ -29,7 +29,7 @@ it 'returns an error message' do subject - expect(json[:confirmation_token]).to eq(['is invalid']) + expect(json[:confirmation_token]).to eq([ 'is invalid' ]) end it 'does not confirm the user' do diff --git a/spec/requests/users/passwords/create_spec.rb b/spec/requests/users/passwords/create_spec.rb index b36aaf6..497e64e 100644 --- a/spec/requests/users/passwords/create_spec.rb +++ b/spec/requests/users/passwords/create_spec.rb @@ -38,7 +38,7 @@ it 'returns an error message' do subject - expect(json[:errors][:email]).to eq(['not found']) + expect(json[:errors][:email]).to eq([ 'not found' ]) end it 'does not send an email' do diff --git a/spec/requests/users/passwords/update_spec.rb b/spec/requests/users/passwords/update_spec.rb index a27cf46..17379fb 100644 --- a/spec/requests/users/passwords/update_spec.rb +++ b/spec/requests/users/passwords/update_spec.rb @@ -39,7 +39,7 @@ it 'returns an error message' do subject - expect(json[:errors][:reset_password_token]).to eq(['is invalid']) + expect(json[:errors][:reset_password_token]).to eq([ 'is invalid' ]) end it 'does not update the password' do @@ -57,7 +57,7 @@ it 'returns an error message' do subject - expect(json[:errors][:password]).to eq(["can't be blank"]) + expect(json[:errors][:password]).to eq([ "can't be blank" ]) end it 'does not update the password' do @@ -75,7 +75,7 @@ it 'returns an error message' do subject - expect(json[:errors][:password]).to eq(['is too short (minimum is 6 characters)']) + expect(json[:errors][:password]).to eq([ 'is too short (minimum is 6 characters)' ]) end it 'does not update the password' do