Skip to content

Upgrade rails 6 to 8#408

Draft
dschmura wants to merge 35 commits intostagingfrom
upgrade_rails_6_to_8
Draft

Upgrade rails 6 to 8#408
dschmura wants to merge 35 commits intostagingfrom
upgrade_rails_6_to_8

Conversation

@dschmura
Copy link
Copy Markdown
Collaborator

@dschmura dschmura commented Jan 8, 2026

MiClassrooms Upgrade Summary

Overview

This document summarizes all changes made during the extended upgrade session, migrating MiClassrooms from Rails 6.1 with Webpacker to a modern Rails 8.1 stack with importmap-rails, Tailwind CSS v4, and SolidQueue.


Impact Metrics

Build System Improvements

Metric Before (Webpacker) After (importmap-rails) Improvement
Node.js Required Yes No Eliminated dependency
node_modules/ Size ~200-500MB typical 0 MB 100% reduction
package.json Dependencies 20+ packages 0 packages 100% reduction
JS Build Time 5-15 seconds 0 seconds (no build) No compilation needed
Dev Server Processes 3 (web, js, css) 3 (web, css, jobs) Same, but simpler
Importmap Pins N/A 12 pins Minimal configuration

Asset Sizes

Asset Size Notes
Compiled Tailwind CSS 60 KB Production-ready
Pannellum (vendored) 66 KB 360° panorama viewer
Bigger Picture (CDN) ~15 KB Lightbox library

Database Query Improvements

N+1 Fix #1: Room Thumbnails & Building Association (rooms#index)

Metric Before After Improvement
Building lookup queries 1 per room displayed 1 batch query ~97% reduction (assuming 30 rooms/page)
Room thumbnail queries 1 per room displayed 1 batch query ~97% reduction
Total queries (30 rooms) ~60+ queries 2 queries ~97% fewer queries

Problem: View used Building.find_by() instead of eager-loaded room.building, and room thumbnails were not eager-loaded.

Solution: Updated to includes(:room_contact, :room_image_attachment, :building)

N+1 Fix #2: Building Images on Rooms Index

Metric Before After Improvement
Building image queries 43 queries (1 per building) 1 batch query 97.7% reduction
ActiveRecord time ~50-60ms ~8-10ms ~80% faster

Problem: Building images were loaded individually when rendering the building filter sidebar.

Solution: Added includes(:building_image_attachment) to the @buildings query.

Infrastructure Simplification

Service Before After Benefit
Redis Required Not needed One less service to manage
Node.js/npm Required Not needed Simpler CI/CD pipelines
Sidekiq Separate process SolidQueue (same DB) Unified PostgreSQL stack

Dependency Reduction

Category Before After Removed
Ruby Gems 40+ 36 redis, sidekiq, spring, webpacker, cssbundling-rails
npm Packages 20+ 0 All Node.js dependencies
External Services Redis None PostgreSQL handles everything

1. Rails Version Upgrades

Rails 6.1 → 7.0

  • Updated gem dependencies for Rails 7.0 compatibility
  • Resolved deprecation warnings

Rails 7.0 → 7.1

  • Updated to Rails 7.1.6
  • Addressed breaking changes in ActiveRecord and ActionView

Rails 7.1 → 7.2

  • Completed Rails 7.2 upgrade

Rails 7.2 → 8.0 → 8.1

  • Upgraded to Rails 8.1.1 (current)
  • Fixed Rails 8.x and Ruby 3.4 compatibility issues
  • Upgraded Sidekiq to 7.3.10 for Rails 8.1 compatibility

2. JavaScript Build System Migration

Webpacker → jsbundling-rails

  • Removed Webpacker entirely
  • Migrated to jsbundling-rails as an intermediate step
  • Updated all JavaScript entry points

jsbundling-rails → importmap-rails

  • Eliminated Node.js dependency entirely
  • Configured config/importmap.rb for all JavaScript dependencies
  • Migrated Stimulus controllers to work with importmap
  • Created app/javascript/controllers/index.js for manual controller registration

Files Changed

  • Removed: package.json, yarn.lock, node_modules/
  • Removed: bin/yarn, bin/webpack, bin/webpack-dev-server
  • Added: config/importmap.rb
  • Updated: app/javascript/application.js, app/javascript/controllers/index.js

3. CSS/Tailwind Migration

Tailwind CSS v3.4 → v4.1

  • Major version upgrade with breaking changes
  • Updated color utilities, spacing, and configuration syntax

cssbundling-rails → tailwindcss-rails

  • Eliminated npm/npx dependency for CSS
  • Installed tailwindcss-rails ~> 4.0 gem
  • Moved CSS from app/assets/stylesheets/application.tailwind.css to app/assets/tailwind/application.css
  • Updated Procfile.dev to use bin/rails tailwindcss:watch

CSS File Location

app/assets/tailwind/application.css  # Main Tailwind entry point
app/assets/builds/tailwind.css       # Compiled output

4. Background Jobs Migration

Redis/Sidekiq → SolidQueue/SolidCable

  • Eliminated Redis dependency
  • Installed gems:
    • solid_queue ~> 1.2
    • solid_cable ~> 3.0
    • mission_control-jobs ~> 1.1

Database Configuration

Updated config/database.yml for multi-database setup:

development:
  primary:
    database: mi_classrooms_development
  queue:
    database: mi_classrooms_queue_development
    migrations_paths: db/queue_migrate
  cable:
    database: mi_classrooms_cable_development
    migrations_paths: db/cable_migrate

Queue Adapter

Updated config/application.rb:

config.active_job.queue_adapter = :solid_queue

Monitoring

  • Replaced Sidekiq::Web with Mission Control at /jobs
  • Protected by authentication (admin email only)

Removed

  • redis gem
  • sidekiq gem
  • config/sidekiq.yml

5. Third-Party Library Updates

Lightbox: lightgallery → Bigger Picture

  • Replaced lightgallery.js with bigger-picture (smaller, modern)
  • Updated lightbox_controller.js
  • CDN-hosted via importmap

Panorama Viewer: Pannellum

  • Vendored Pannellum library (vendor/javascript/pannellum.js)
  • CSS loaded from unpkg CDN
  • Made keyboard accessible (see Accessibility section)

Removed Unused Dependencies

  • nouislider (unused)
  • capacity-slider (unused)

6. Spring Removal

Changes

  • Removed spring and spring-watcher-listen gems
  • Deleted config/spring.rb
  • Deleted bin/spring
  • Updated bin/rails and bin/rake to remove Spring loading

Rationale

Spring is deprecated in Rails 7.1+ and no longer provides significant benefits with modern hardware.


7. Accessibility Improvements

Skip-to-Content Link (Site-wide)

  • Fixed skip link to target #main (the actual main content)
  • Removed redundant empty <div id="maincontent"> from 7 views
  • Fixed duplicate IDs on homepage buttons

Panorama Keyboard Accessibility

  • Removed aria-hidden="true" and focusable="false" from panorama
  • Added role="application" and descriptive aria-label
  • Made load button focusable (tabindex="0")
  • Added keyboard activation (Enter/Space to load)
  • Auto-focus panorama after loading for arrow key navigation

Files Modified

  • app/views/layouts/application.html.erb
  • app/views/rooms/_room_panorama.html.erb
  • app/javascript/controllers/pannellum_controller.js
  • Multiple view files (announcements, buildings, pages, rooms)

8. Performance Fixes

N+1 Query Fixes

  • Fixed N+1 queries on rooms#index page
  • Fixed N+1 query for building images on rooms index

Bug Fixes

  • Removed duplicate Atlassian Jira issue collector script (was in both header and footer)
  • Fixed style issues and Gemfile duplication

9. Announcements CRUD Refactor

Problem

The announcements controller had a non-RESTful pattern:

  • Custom cancel action using GET request that modified session state
  • Session-based return URL tracking (session[:return_to])
  • Missing new, create, and destroy actions
  • No ability to create or delete announcements

Solution

Refactored to standard Rails CRUD pattern:

Controller Changes

  • Removed cancel action and session-based return tracking
  • Added new, create, and destroy actions
  • Simplified edit and update to redirect to announcements_path

Route Changes

# Before
resources :announcements
get 'announcements/:id/cancel', to: "announcements#cancel", as: 'announcements_cancel'

# After
resources :announcements

Model Changes

Added location validation to Announcement model:

LOCATIONS = %w[home_page find_a_room_page about_page].freeze
validates :location, presence: true, inclusion: { in: LOCATIONS }

Policy Changes

Updated AnnouncementPolicy for Pundit authorization:

  • Added create? and destroy? permissions
  • Removed cancel? permission

View Changes

  • Index view: Reorganized with sections grouped by location type, each with descriptions of where announcements appear
  • Form partial: Updated cancel link to use announcements_path, added location dropdown for new announcements
  • New view: Created new.html.erb template

Modified Files

  • config/routes.rb
  • app/controllers/announcements_controller.rb
  • app/models/announcement.rb
  • app/policies/announcement_policy.rb
  • app/views/announcements/index.html.erb
  • app/views/announcements/_form.html.erb
  • app/views/announcements/new.html.erb (created)

Test Configuration Fix

Moved ActiveJob::Base.queue_adapter = :test from spec/rails_helper.rb (where it ran on every test) to config/environments/test.rb (where it runs once at boot). This follows Rails conventions for environment-specific configuration.


10. Files Removed (Cleanup)

Build Tools

  • bin/yarn
  • bin/webpack
  • bin/webpack-dev-server
  • bin/spring
  • package.json
  • yarn.lock
  • node_modules/

Configuration

  • config/spring.rb
  • config/sidekiq.yml
  • .asdf-plugins entries for nodejs/yarn

Updated .gitignore

  • Removed webpack/yarn entries
  • Kept relevant Rails entries

11. Current Tech Stack

Component Before After
Rails 6.1.7 8.1.1
Ruby 3.3.4 3.3.4
JS Bundler Webpacker importmap-rails
CSS Tailwind v3 + cssbundling Tailwind v4 + tailwindcss-rails
Background Jobs Sidekiq + Redis SolidQueue (PostgreSQL)
ActionCable Redis SolidCable (PostgreSQL)
Node.js Required Yes No

11. Development Workflow

Starting Development Server

bin/dev

This runs (via Procfile.dev):

  • web: Rails server on port 3000
  • css: Tailwind CSS watcher
  • jobs: SolidQueue worker

Monitoring Background Jobs

Visit /jobs (requires admin authentication)


12. Deployment Considerations

  1. Database Migrations: Run migrations for SolidQueue and SolidCable schemas
  2. Remove Redis: No longer required for jobs or ActionCable
  3. Environment Variables: Update any Sidekiq/Redis-specific env vars
  4. Asset Compilation: bin/rails assets:precompile now handles Tailwind
  5. Procfile: Update for production to run SolidQueue workers

  Phase 0 of Rails 8.1 upgrade: Migrate frontend build system from
  Webpacker to jsbundling-rails with esbuild before upgrading Rails.

  Frontend Changes:
  - Add jsbundling-rails and cssbundling-rails gems
  - Replace Webpacker with esbuild for JavaScript bundling
  - Upgrade Tailwind CSS from v2.1.1 to v3.x
  - Create new app/javascript/ structure with explicit Stimulus imports
  - Remove require.context() dynamic loading (not compatible with esbuild)

  New Stimulus Controllers:
  - flash_controller.js - Auto-dismiss flash messages (replaces flash_timeout.js)
  - mobile_menu_controller.js - Toggle sidebar (replaces mobile_menu.js)
  - feedback_controller.js - Jira issue collector (replaces feedback.js)

  Migrated Controllers (updated to @hotwired/stimulus):
  - autosubmit, capacity_slider, confirmation, infopanel
  - pannellum, updatebuilding, updateroom, visibility

  View Updates:
  - Replace stylesheet_pack_tag/javascript_pack_tag with standard asset helpers
  - Update views to use new Stimulus controllers via data attributes
  - Remove legacy javascript_include_tag references

  Removed:
  - config/webpacker.yml and config/webpack/ directory
  - babel.config.js
  - Legacy JS files in app/assets/javascripts/
  - yarn.lock (replaced with package-lock.json via npm)

  Build commands:
  - npm run build (JavaScript via esbuild)
  - npm run build:css (Tailwind CSS)
  - bin/dev (runs both with foreman)
  Phase 1 of Rails upgrade (6.1 → 7.0):

  - Update rails gem to ~> 7.0.0 (installs 7.0.10)
  - Update config.load_defaults to 7.0
  - Replace hotwire-rails with turbo-rails and stimulus-rails
  - Migrate Devise from fork to official gem (~> 4.9)
  - Add Devise Turbo settings (error_status, redirect_status)
  - Update Pundit include to Pundit::Authorization
  - Pin Pagy to ~> 6.0 and simplify initializer
  - Add Ruby 3.4 compatibility gems (mutex_m, drb, observer)
  - Update puma (~> 6.0), rspec-rails (~> 6.0), responders (~> 3.1)
  - Add new_framework_defaults_7_0.rb initializer

  All tests pass. Next: Phase 2 (Rails 7.1)
  Phase 2 of Rails upgrade (7.0 → 7.1):

  - Update rails gem to ~> 7.1.0 (installs 7.1.6)
  - Update config.load_defaults to 7.1
  - Remove new_framework_defaults_6_1.rb (settings now default)
  - Remove new_framework_defaults_7_0.rb (settings now default)

  All tests pass. Next: Phase 3 (Rails 7.2)
  Summary:
  - Rails: 7.1.6 → 7.2.3
  - Updated config.load_defaults to 7.2

  All tests pass. Draft commit message:

  Upgrade to Rails 7.2.3

  Phase 3 of Rails upgrade (7.1 → 7.2):

  - Update rails gem to ~> 7.2.0 (installs 7.2.3)
  - Update config.load_defaults to 7.2

  All tests pass. Next: Phase 4 (Rails 8.0)
  Summary:
  - Rails: 7.2.3 → 8.0.4
  - Updated config.load_defaults to 8.0
  - Commented out annotate gem (not compatible with Rails 8.0 yet)

  All tests pass. Draft commit message:

  Upgrade to Rails 8.0.4

  Phase 4 of Rails upgrade (7.2 → 8.0):

  - Update rails gem to ~> 8.0.0 (installs 8.0.4)
  - Update config.load_defaults to 8.0
  - Comment out annotate gem (not yet compatible with Rails 8)

  All tests pass. Next: Phase 5 (Rails 8.1)
  Phase 5 of Rails upgrade (8.0 → 8.1) - FINAL:

  - Update rails gem to ~> 8.1.0 (installs 8.1.1)
  - Update config.load_defaults to 8.1

  Complete upgrade path: Rails 6.1.7.9 → 8.1.1
- Add comprehensive tests for Room, Building, RoomCharacteristic,
  Note, and Floor models following behavior-over-implementation pattern
- Create new factories: users, notes, floors
- Fix existing factories with valid Faker methods (replace deprecated
  Faker::Company.department, Faker::String.random, unbounded numbers)
- Configure ActiveJob test adapter to prevent Redis dependency in tests
- Fix fixture_paths deprecation (singular to plural array)
- Add test fixtures for image uploads
Rails 8.1 deprecated the built-in sidekiq adapter and requires
Sidekiq 7.3.3+ to use the gem's native adapter instead.
- Update render paths to use standard partial syntax without
  leading './' prefix (layouts/_headness.html.erb)
- Add explicit require for 'benchmark' which is being removed
  from Ruby stdlib in 3.4+ (api_update_database.rake)
Problem:
- View used Building.find_by() instead of eager-loaded room.building
- Room thumbnail images were not eager-loaded
- Caused excessive database queries per page load

Changes:
- Update includes to: :room_contact, :room_image_attachment, :building
- Replace Building.find_by(bldrecnbr: room.building_bldrecnbr) with
  room.building in _room_row.html.erb (4 occurrences)

Note: Notes associations (.alert scope) intentionally not eager-loaded
as the scope triggers separate queries regardless of preloading.

Performance improvement:
- Eliminated redundant Building.find_by queries (was 1 per room)
- Added eager loading for room thumbnails
- Reduced database round-trips significantly
Major upgrade to Tailwind CSS v4 with CSS-first configuration approach.

Changes:
- Migrate from tailwind.config.js to CSS @theme directive
- Replace @tailwind directives with @import 'tailwindcss'
- Update PostCSS config to use @tailwindcss/postcss
- Add @tailwindcss/cli for build scripts
- Normalize breakpoints to Tailwind defaults (sm=640px, md=768px, lg=1024px)
- Fix deprecated ring-opacity utilities (ring-black/5 syntax)
- Remove autoprefixer (now built into v4)

Template updates:
- Convert ring-black ring-opacity-5 → ring-black/5
- Convert ring-red-400 ring-opacity-30 → ring-red-400/30

Build performance improved from ~400ms to ~80ms.
Replace esbuild JavaScript bundling with browser-native ES modules via
importmap-rails, eliminating the JS build step and reducing complexity.

## JavaScript Migration
- Add importmap-rails gem, remove jsbundling-rails
- Configure importmap.rb with pins for all packages
- Vendor third-party packages to vendor/javascript/:
  - tailwindcss-stimulus-components
  - stimulus-lightbox
  - nouislider
  - lightgallery
  - pannellum
- Remove unused dependencies (flatpickr, stimulus-flatpickr)
- Update layout to use javascript_importmap_tags
- Remove JS build from Procfile.dev (CSS-only now)

## Tailwind CSS v4 Upgrade
- Update package.json to Tailwind CSS v4.1 with @tailwindcss/cli
- Add @source directive to scan vendor/javascript for classes

## Turbo Compatibility Fixes
- Replace Rails UJS method: with data: { turbo_method: }
- Replace confirm: with data: { turbo_confirm: }

## Other Changes
- Enable CSP nonce generation for importmap inline scripts
- Add Trix CSS from CDN for ActionText rich text editor
- Simplify announcements controller update action
- Change announcements cancel route from POST to GET
Add eager loading for building_image_attachment to the @buildings query
in RoomsController#index to prevent N+1 queries when rendering building
images in the view.

## Performance Impact
- Before: 43 separate queries (1 per building) for image attachments
- After: 1 batch query for all building image attachments
- Estimated savings: ~8-10ms in ActiveRecord time per request
The capacity slider feature was replaced with simple number input fields
but the JavaScript dependencies were never removed.

## Removed
- nouislider.js (96KB vendored file)
- capacity_slider_controller.js (unused Stimulus controller)
- Related imports and registrations from controllers/index.js
- Pin from importmap.rb

## Impact
- ~98KB reduction in JavaScript payload
- No functionality change (capacity filtering uses number fields)
Migrate from lightgallery + stimulus-lightbox (116KB) to Bigger Picture
(77KB), reducing JavaScript bundle size by 39KB (34%).

Benefits:
- Native ES module compatible with importmap-rails (no bundling required)
- Improved accessibility: keyboard navigation (arrow keys, Escape),
  focus trapping, and ARIA attributes for screen readers
- Smaller footprint with simpler, more maintainable API

Changes:
- Create custom lightbox_controller.js Stimulus controller
- Add bigger-picture.js to vendor/javascript/
- Load bigger-picture.css from CDN in layout
- Update importmap.rb with new pin
- Simplify rooms/show.html.erb lightbox markup
- Remove lightgallery.js and stimulus-lightbox.js
The script was loaded in both _header.html.erb and _footer.html.erb,
causing a JavaScript error: "trigger_51ecac03 is not a function".
Keeping the script in the footer only resolves the duplicate loading issue.
Changes:
- Load bigger-picture and tailwindcss-stimulus-components from jspm.io CDN
- Remove vendored bigger-picture.js and tailwindcss-stimulus-components.js
- Only pannellum.js remains vendored (no ESM available on CDN)
- Fix pannellum controller to reference window.pannellum for global access
- Add pannellum CSS from unpkg CDN
- Fix image variant resize syntax for Rails 7+ (resize_to_limit)
- Convert panorama styles to Tailwind CSS v4 syntax
- Add semi-transparent load button styling for pannellum

Vendored JS reduced from 149KB to 68KB (pannellum only).
Spring is no longer included in Rails 7.1+ by default. Modern hardware
and improved Rails boot times make it unnecessary, and it can cause
subtle caching bugs.
Replace Sidekiq with SolidQueue for background job processing and
Redis with SolidCable for ActionCable. Uses PostgreSQL-backed queues
instead of Redis, simplifying infrastructure requirements.

- Add solid_queue, solid_cable, mission_control-jobs gems
- Remove redis and sidekiq gems
- Configure multi-database setup for queue and cable
- Replace Sidekiq::Web with MissionControl::Jobs at /jobs
- Update Procfiles to use bin/jobs
Replace npm-based Tailwind CSS build with the standalone tailwindcss-rails
gem (v4), eliminating Node.js as a dependency.

- Replace cssbundling-rails with tailwindcss-rails ~> 4.0
- Move CSS from app/assets/stylesheets/ to app/assets/tailwind/
- Remove package.json, yarn.lock, and node_modules
- Update Procfile.dev to use bin/rails tailwindcss:watch
- Add tailwind stylesheet link to layout
Clean up leftover files and references from the migration to
importmap-rails and tailwindcss-rails:

- Remove bin/yarn, bin/webpack, bin/webpack-dev-server, bin/spring
- Remove Spring loading from config/boot.rb
- Remove yarn call from bin/setup
- Remove node_modules path from assets.rb
- Remove nodejs/yarn from .asdf-plugins
- Remove webpack/yarn entries from .gitignore
- Update README with Ruby 3.3.4, Rails 8.1, SolidQueue
- Update skip link to target #main (the actual main content area)
- Remove redundant empty div#maincontent elements from views
- Fix duplicate IDs on index page buttons and clean up unnecessary attrs
- Remove aria-hidden="true" and focusable="false" that blocked accessibility
- Add role="application" to indicate interactive widget
- Add descriptive aria-label with keyboard instructions
- Add tabindex="0" to enable keyboard focus

Pannellum already supports keyboard navigation (arrow keys to pan,
+/- to zoom) - this enables users to actually reach and use it.
- Add keyboard support to Pannellum load button (Enter/Space to activate)
- Make load button focusable with proper ARIA attributes
- Auto-focus panorama container after loading for arrow key navigation
- Fix HTML attribute quoting in panorama partial
- Escape room display name in aria-label to prevent XSS
@dschmura dschmura requested a review from Copilot January 8, 2026 14:19
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades the MiClassrooms application from Rails 6.1 to Rails 8.1, eliminating Node.js dependencies by migrating from Webpacker to importmap-rails, upgrading Tailwind CSS from v3 to v4, and replacing Redis/Sidekiq with PostgreSQL-backed SolidQueue for background jobs. The changes significantly simplify the build system, reduce dependencies, and improve performance through N+1 query optimizations.

Key changes:

  • Rails framework upgraded from 6.1.7 to 8.1.1 with Ruby 3.3.4
  • JavaScript bundling migrated from Webpacker to importmap-rails, eliminating Node.js dependency
  • Background jobs migrated from Sidekiq/Redis to SolidQueue/SolidCable (PostgreSQL-backed)
  • Tailwind CSS upgraded from v3 to v4 with native Rails gem support
  • N+1 query optimizations implemented on rooms index page
  • Comprehensive test coverage added for Room, RoomCharacteristic, Note, Floor, and Building models

Reviewed changes

Copilot reviewed 94 out of 111 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Gemfile Updated Rails to 8.1, added Ruby 3.4 stdlib gems, replaced Sidekiq with SolidQueue, removed Webpacker
config/database.yml Added multi-database support for queue and cable databases
config/importmap.rb New importmap configuration for JavaScript dependencies
app/javascript/application.js New importmap entry point replacing Webpacker
app/javascript/controllers/index.js Manual Stimulus controller registration for importmap
app/assets/tailwind/application.css New Tailwind CSS v4 configuration with custom theme variables
config/routes.rb Replaced Sidekiq web UI with Mission Control, changed announcement cancel route to GET
app/controllers/rooms_controller.rb Added eager loading to fix N+1 queries on rooms index
app/views/**/*.erb Updated Tailwind classes for v4 compatibility, fixed accessibility issues
spec/**/*_spec.rb Added comprehensive model test coverage

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@dschmura dschmura force-pushed the upgrade_rails_6_to_8 branch from 36cbc37 to 2db779c Compare January 8, 2026 14:27
Configure the test queue adapter in config/environments/test.rb
instead of setting it in every RSpec example. This follows Rails
conventions for environment-specific configuration and improves
test performance by avoiding redundant setup on each test.
- Add new, create, and destroy actions to AnnouncementsController
- Remove non-RESTful cancel route and session-based return tracking
- Add LOCATIONS constant and validation to Announcement model
- Update Pundit policy with create? and destroy? permissions
- Reorganize index view with sections grouped by location type
- Add descriptions for each announcement location
- Support pre-selecting location when creating from empty section
- Create new.html.erb view with location selector
@dschmura dschmura requested a review from Copilot January 8, 2026 15:23

This comment was marked as outdated.

@dschmura dschmura requested a review from Copilot January 8, 2026 15:31

This comment was marked as outdated.

Replace string interpolation with Rails.root.join() for cleaner,
more idiomatic path handling in RSpec configuration.
@dschmura dschmura requested a review from Copilot January 8, 2026 15:41

This comment was marked as outdated.

@dschmura dschmura requested a review from Copilot January 8, 2026 15:46

This comment was marked as outdated.

Use build instead of create in after(:build) callback so that
build(:note) no longer creates database records for building
and room. Add after(:create) callback to persist noteable only
when the note itself is being persisted.
@dschmura dschmura requested a review from Copilot January 8, 2026 15:50

This comment was marked as outdated.

@dschmura dschmura requested a review from Copilot January 8, 2026 16:02

This comment was marked as outdated.

@dschmura dschmura requested a review from rsmoke January 13, 2026 15:12
@dschmura dschmura self-assigned this Jan 13, 2026
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