Skip to content

Handle symbol argument in find_or_initialize_with_errors#5840

Open
MahmoudBakr23 wants to merge 1 commit intoheartcombo:mainfrom
MahmoudBakr23:fix-find-or-initialize-with-errors-symbol
Open

Handle symbol argument in find_or_initialize_with_errors#5840
MahmoudBakr23 wants to merge 1 commit intoheartcombo:mainfrom
MahmoudBakr23:fix-find-or-initialize-with-errors-symbol

Conversation

@MahmoudBakr23
Copy link
Copy Markdown

Fixes #5588

What

find_or_initialize_with_errors now accepts a bare symbol (or string) for required_attributes, in addition to the documented array form.

Why

The method's contract required an array, but didn't enforce it. When a caller passed a bare symbol — as reset_password_by_token does internally when delegating through find_or_initialize_with_error_by — two things broke silently:

  1. required_attributes.size returns the character count of the symbol name (e.g. 5 for :email) instead of 1, so the size comparison against attributes.size always fails and the record is never returned even when it exists.
  2. required_attributes.each iterates over the symbol as an enumerator of its characters (Ruby 2) or raises NoMethodError (Ruby 3), so the error-building block at the end crashes before adding any validation errors.

The root cause is that the method does no normalisation before using required_attributes as a collection.

Fix

One Array() call at the entry point:

required_attributes = Array(required_attributes)

Array() is the standard Ruby idiom for this normalisation:

  • Array([:email])[:email] (existing array callers are unaffected)
  • Array(:email)[:email] (bare symbol now works)
  • Array("email")["email"] (bare string now works)
  • Array(nil)[] (nil is safe)

All existing callers already pass arrays, so there is zero behaviour change for the current codebase.

Tests

Two new cases added to test/models/authenticatable_test.rb, covering the symbol path for both the found and not-found branches:

find_or_initialize_with_errors accepts a single symbol as required_attributes
find_or_initialize_with_errors adds error when given a single symbol and record is not found

Full test run: 9 runs, 10 assertions, 0 failures, 0 errors, 0 skips.

The method documented required_attributes as accepting an array, but did
not guard against a bare symbol being passed directly. When a symbol was
given, the subsequent .each call on required_attributes raised NoMethodError
and .size returned the character count of the symbol name rather than 1,
so the size comparison against attributes.size always failed.

Wrapping required_attributes with Array() at the entry point normalises
all valid inputs (symbol, string, array) without changing behaviour for
existing callers that already pass an array.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Error when using find_or_initialize_with_errors method with required_attributes as a symbol

1 participant