Skip to content

Upgrade Rails from 7.0.5 to 8.0.5 - #530

Open
mcfiredrill with Copilot wants to merge 4 commits into
mainfrom
copilot/upgrade-app-rails-version
Open

mcfiredrill with Copilot wants to merge 4 commits into
mainfrom
copilot/upgrade-app-rails-version

Conversation

Copilot AI commented Apr 18, 2026 •

Copy link
Copy Markdown
Contributor

Upgrades the app to Rails 8.0.5 from 7.0.5, addressing all breaking changes and deprecated APIs.

Gem updates

  • rails 7.0.5 → 8.0.5
  • rspec-rails ~3.5 → ~7.0
  • active_model_serializers ~0.10.0 → ~0.10.14 (drops < 7.1 upper bound)
  • exception_notification switched from mcfiredrill fork to official gem 5.0 (supports Rails 7.1–9)
  • kt-paperclip ~6.4 → ~7.0
  • Removed spring, headless, selenium-webdriver < 3.0 pin

Rails 8 breaking changes

  • Enum syntax — all 13 declarations migrated from removed hash syntax to positional args:
    # before
    enum status: [:active, :archived]
    # after
    enum :status, [:active, :archived]
  • Rails.application.secrets — replaced 5 usages across 4 files with direct ENV[] access (secrets.yml was already reading from ENV in production anyway)
  • cache_classes → enable_reloading (inverted) in all environment configs
  • show_exceptions = false → show_exceptions = :none
  • Devise::TestHelpers → Devise::Test::ControllerHelpers
  • fixture_path → fixture_paths
  • alias_attribute for non-DB attributes — Rails 8 now validates that alias_attribute targets are real DB columns. Replaced with alias_method for ActiveStorage attachment aliases (as_image) in User, ScheduledShow, and ShowSeries models.

Config modernization

  • Boot files use require_relative / __dir__ instead of File.expand_path(__FILE__)
  • Explicitly set config.active_record.belongs_to_required_by_default = false to preserve original behavior (the app was built without config.load_defaults, so belongs_to associations were never required by default)
  • Added config.active_support.to_time_preserves_timezone = :zone to silence deprecation

Deployment notes

  • config/secrets.yml is no longer referenced in code; LIQ_SECRET and STEREO_TOOL_KEY must be in ENV
  • exception_notification fork's only delta was a Discord Content-Type header for the Slack notifier — verify Discord error webhooks still work after deploy

- Update Gemfile: rails 8.0.5, rspec-rails 7.x, active_model_serializers 0.10.14+,
  exception_notification 5.0, kt-paperclip 7.x, remove spring/headless
- Modernize config files: use require_relative, __dir__ patterns
- Update environment configs: cache_classes → enable_reloading,
  show_exceptions = false → :none
- Add config.load_defaults 7.0 and timezone deprecation fix
- Convert all enum declarations to new positional argument syntax (Rails 8)
- Replace Rails.application.secrets with ENV vars
- Fix Devise::TestHelpers → Devise::Test::ControllerHelpers in specs
- Update fixture_path to fixture_paths (plural)
- Remove bin/spring

Agent-Logs-Url: https://github.com/datafruits/streampusher-api/sessions/4c3865e2-e9cd-417d-803f-2a0895191055

Co-authored-by: mcfiredrill <66243+mcfiredrill@users.noreply.github.com>
@mcfiredrill

Copy link
Copy Markdown
Member

@copilot fix the failing tests

Copilot AI and others added 2 commits April 19, 2026 02:34
…ions

The original app had no config.load_defaults, so belongs_to associations
were never required by default. Adding config.load_defaults 7.0 activated
belongs_to_required_by_default=true, causing Radio.find_or_create_by! in
db/seeds to fail because default_playlist is created via after_create
callback. Instead, explicitly set belongs_to_required_by_default=false to
preserve the original behavior.

Agent-Logs-Url: https://github.com/datafruits/streampusher-api/sessions/a3a06d8c-9a92-47eb-ba62-c24f5192a459

Co-authored-by: mcfiredrill <66243+mcfiredrill@users.noreply.github.com>
Agent-Logs-Url: https://github.com/datafruits/streampusher-api/sessions/a3a06d8c-9a92-47eb-ba62-c24f5192a459

Co-authored-by: mcfiredrill <66243+mcfiredrill@users.noreply.github.com>

Copilot AI commented Apr 19, 2026 •

Copy link
Copy Markdown
Contributor Author

@copilot fix the failing tests

The CI failure was caused by config.load_defaults 7.0 which I added — this activated belongs_to_required_by_default = true, but the original app never had this enabled. This broke Radio.find_or_create_by! in db:seed because default_playlist is created via an after_create callback and can't exist at creation time.

Fixed in e1a8e89 by removing config.load_defaults 7.0 and instead explicitly setting config.active_record.belongs_to_required_by_default = false to preserve the original behavior.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • postgres
    • Triggering command: /usr/bin/ruby3.2 ruby3.2 /home/REDACTED/work/streampusher-api/streampusher-api/vendor/bundle/ruby/3.2.0/bin/rspec --no-color spec/models/user_spec.rb /opt/local/include -I /sw/include -I /home/REDACTED/work/streampusher-api/streampusher-api/vendor/taglib/include --gdwarf-5 --64 -o -I lib/include -I /usr/bin/x86_64--I -I /usr/include/rub-I -I api/vendor/tagli-I (dns block)
  • s3.amazonaws.com
    • Triggering command: /usr/bin/ruby3.2 /usr/bin/ruby3.2 -I/usr/lib/ruby/vendor_ruby extconf.rb --gdwarf-5 --64 -o raindrops.o /tmp/ccizFOky.s -I y-3.2.0 -I as -I by-3.2.0 -I ndor/bin/as -I y-3.2.0 -I as (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@mcfiredrill

Copy link
Copy Markdown
Member

tests are still failing @copilot

ArgumentError: User model aliases as_image, but as_image is not an attribute. Use alias_method :avatar, :as_image or define the method manually. (ArgumentError)

      raise ArgumentError, "#{self.name} model aliases `#{old_name}`, but `#{old_name}` is not an attribute. " \
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

/home/runner/work/streampusher-api/streampusher-api/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.5/lib/active_record/attribute_methods.rb:91:in `alias_attribute_method_definition'

…ments

Rails 8 validates that alias_attribute targets are real DB attributes.
ActiveStorage's has_one_attached creates methods, not DB columns, so
alias_attribute fails. Replace with alias_method for:
- User: avatar, image (→ as_image), thumb_avatar_url (→ thumb_image_url)
- ScheduledShow: image, image= (→ as_image, as_image=)
- ShowSeries: image (→ as_image), moved after has_one_attached declaration

Agent-Logs-Url: https://github.com/datafruits/streampusher-api/sessions/3e797b92-f1d3-4be1-aa52-18043bf0c94c

Co-authored-by: mcfiredrill <66243+mcfiredrill@users.noreply.github.com>

Copilot AI commented Apr 19, 2026 •

Copy link
Copy Markdown
Contributor Author

tests are still failing @copilot

ArgumentError: User model aliases as_image, but as_image is not an attribute. Use alias_method :avatar, :as_image or define the method manually. (ArgumentErr...

Fixed in 5e8f51e. Rails 8's alias_attribute now validates that the target is a real DB column/attribute. Since as_image is defined by has_one_attached (not a DB column), replaced all alias_attribute calls with alias_method in User, ScheduledShow, and ShowSeries. Also moved the alias in ShowSeries to after the has_one_attached declaration so the method exists at alias time.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • postgres
    • Triggering command: /usr/bin/ruby3.2 ruby3.2 /home/REDACTED/work/streampusher-api/streampusher-api/vendor/bundle/ruby/3.2.0/bin/rspec spec/models/user_spec.rb -pie -I b/include -I by-3.2.0 rame-pointer kward r-strong b/include -fr ecurity false as unicorn_http.o y-3.2.0/ruby/bacDESTDIR= mkmf.log api/vendor/taglisitelibdir=./.gem.20260419-6410-1bqvuz (dns block)
  • s3.amazonaws.com
    • Triggering command: /usr/bin/ruby3.2 /usr/bin/ruby3.2 -I/usr/lib/ruby/vendor_ruby extconf.rb --gdwarf-5 --64 -o ossl_ns_spki.o /tmp/cca9CWwO.s -I y-3.2.0 -I as -I by-3.2.0 -I kward -I y-3.2.0 -I -gcc (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants