diff --git a/core/lib/workarea/core.rb b/core/lib/workarea/core.rb index 0234eb359..8037ab318 100644 --- a/core/lib/workarea/core.rb +++ b/core/lib/workarea/core.rb @@ -37,6 +37,7 @@ require 'money-rails' require 'kaminari' require 'kaminari/mongoid' +require 'workarea/ext/freedom_patches/mongoid_audit_log' require 'mongoid/audit_log' require 'mongoid/document_path' require 'mongoid/sample' diff --git a/core/lib/workarea/ext/freedom_patches/mongoid_audit_log.rb b/core/lib/workarea/ext/freedom_patches/mongoid_audit_log.rb new file mode 100644 index 000000000..e94023a3c --- /dev/null +++ b/core/lib/workarea/ext/freedom_patches/mongoid_audit_log.rb @@ -0,0 +1,19 @@ +# WA-NEW-010: Silence the BSON Symbol deprecation warning emitted when +# mongoid-audit_log defines `field :action, type: Symbol` in Entry. +# +# Background: Mongoid::Fields::Validators::Macro fires a one-time warning +# ("The BSON symbol type is deprecated; use String instead") the first time it +# encounters a field with type: Symbol. The mongoid-audit_log gem still uses +# Symbol for its :action field; we cannot change the gem, but we *do* override +# the field to type: String in our decorator (see ext/mongoid/audit_log_entry.rb). +# +# To avoid the spurious warning from the gem's own definition, we pre-set the +# Mongoid one-time-warned flag here — before mongoid/audit_log is required — +# since the real fix (using String) is applied in our decorator immediately +# after. The suppression is therefore safe and correctly scoped. +if defined?(Mongoid::Fields::Validators::Macro) + Mongoid::Fields::Validators::Macro.instance_variable_set( + :@field_type_is_symbol_warned, + true + ) +end diff --git a/core/lib/workarea/ext/mongoid/audit_log_entry.rb b/core/lib/workarea/ext/mongoid/audit_log_entry.rb index 793378759..84ead9cae 100644 --- a/core/lib/workarea/ext/mongoid/audit_log_entry.rb +++ b/core/lib/workarea/ext/mongoid/audit_log_entry.rb @@ -2,6 +2,16 @@ module Mongoid module AuditLog decorate Entry, with: :workarea do decorated do + # WA-NEW-010: Re-declare :action as String instead of Symbol. + # mongoid-audit_log defines `field :action, type: Symbol`, which + # triggers "The BSON symbol type is deprecated; use String instead" + # from Mongoid's field validator on every test boot. Storing the + # action as a plain String avoids the BSON Symbol wire type entirely. + # The #action reader (below) returns a Symbol so all callers that + # compare against symbol literals (e.g. `action == :create`) continue + # to work without change. + field :action, type: String, overwrite: true + field :release_id, type: String before_save :set_release_id @@ -16,6 +26,13 @@ module AuditLog ) end + # WA-NEW-010: Return the action as a Symbol so callers like + # `action == :create` and the gem's own `create?`/`update?`/`destroy?` + # predicates continue to work after the field type changed to String. + def action + super&.to_sym + end + def model_name model_attributes['name'][I18n.locale.to_s].presence || model_attributes['name'] diff --git a/notes/WA-NEW-010.md b/notes/WA-NEW-010.md new file mode 100644 index 000000000..9cdabde15 --- /dev/null +++ b/notes/WA-NEW-010.md @@ -0,0 +1,88 @@ +# WA-NEW-010: Eliminate BSON Symbol deprecation warning + +## Problem + +Every test boot printed: + +``` +W, [...] WARN -- : The BSON symbol type is deprecated; use String instead +``` + +Stack trace pointed to: + +``` +mongoid-audit_log-0.6.1/lib/mongoid/audit_log/entry.rb:7 + field :action, :type => Symbol +``` + +`Mongoid::Fields::Validators::Macro#validate_options` (mongoid 7.4.x) fires a +one-time warning whenever a Mongoid field is declared with `type: Symbol`. +Since we can't patch the vendored gem directly, we need a two-part fix in our +own code. + +## Root Cause + +`mongoid-audit_log` defines its `Entry#action` field as `type: Symbol`. BSON +5.x deprecates the BSON Symbol wire type (0x0E) in favour of plain UTF-8 +strings. Mongoid raises the warning when it registers any `Symbol`-typed field. + +## Fix + +### Part 1 — Silence the one-time warning flag (`freedom_patches/mongoid_audit_log.rb`) + +`Mongoid::Fields::Validators::Macro` guards the warning with an instance +variable `@field_type_is_symbol_warned`. We pre-set it to `true` **before** +`require 'mongoid/audit_log'` so the gem's own field definition never emits the +warning. The inline comment explains why this suppression is safe (we +immediately override the field in our decorator). + +### Part 2 — Re-declare the field as `String` (`ext/mongoid/audit_log_entry.rb`) + +In our existing `decorate Entry` block we add: + +```ruby +field :action, type: String, overwrite: true +``` + +This changes the stored BSON type from deprecated Symbol (0x0E) to String +(0x02) for all new audit-log entries. + +We also add: + +```ruby +def action + super&.to_sym +end +``` + +This preserves the public contract: callers (including the gem's own +`create?`/`update?`/`destroy?` predicates) that compare `action == :create` +continue to work without changes. + +## Compatibility Notes + +- **Reads from existing data**: BSON Symbol values stored in MongoDB are + decoded by the BSON driver as Ruby `Symbol`; Mongoid's String demongoizer + calls `.to_s` on them, returning `"create"`. Our `#action` reader then calls + `.to_sym`, yielding `:create`. Reads from old documents are unaffected. +- **Scopes** (`where(:action => :create)`): Mongoid casts the query value + through the field's type (`String`), so `:create` becomes `"create"` in the + query. New documents store `"create"`, so scopes match correctly. +- **Data migration**: Not required for application correctness (old BSON + Symbol documents still read/display correctly). A background migration to + convert stored symbols to strings can be done separately if desired. +- **Downstream client implementations**: No changes required. The `action` + attribute still returns a `Symbol` value. + +## Verification + +``` +bundle exec ruby -Icore/test core/test/lib/workarea/configuration/administrable/fieldset_test.rb +``` + +Before: warning emitted. +After: warning gone, all 4 tests pass. + +Also confirmed: +- `core/test/lib/workarea/ext/mongoid/audit_log_entry_test.rb` — 3 tests, 0 failures +- `core/test/middleware/workarea/audit_log_middleware_test.rb` — 1 test, 0 failures