Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/lib/workarea/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
19 changes: 19 additions & 0 deletions core/lib/workarea/ext/freedom_patches/mongoid_audit_log.rb
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions core/lib/workarea/ext/mongoid/audit_log_entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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']
Expand Down
88 changes: 88 additions & 0 deletions notes/WA-NEW-010.md
Original file line number Diff line number Diff line change
@@ -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
Loading