Skip to content

Conversation

@oehlschl
Copy link
Contributor

@oehlschl oehlschl commented Sep 26, 2025

Summary

We sometimes have issues where clients call our APIs and pass integer primary keys instead of slugs, but Model.friendly.find(id) finds a record with the same numeric slug, because our slug candidates are dynamic and in some cases purely numeric.

We'd like to prevent that, and so this PR adds a new configuration option treat_numeric_as_conflict prevent purely numeric slugs and therefore resolve the ambiguity where Model.friendly.find("123") could return either a record with slug="123" OR a record with id=123.

When enabled, purely numeric slug candidates are treated as conflicts and resolved using UUID suffixing, ensuring all slugs contain non-numeric characters that eliminate lookup ambiguity.

Changes

  • Added treat_numeric_as_conflict configuration option to Slugged::Configuration
  • Updated SlugGenerator to detect and reject purely numeric slugs when enabled
  • Added purely_numeric_slug? helper method using Integer() validation (consistent with potential_primary_key?)
  • Expanded test coverage for both default behavior and numeric prevention
  • UPDATE: added Guide documentation and changelog entry

Usage

class Product < ApplicationRecord
  extend FriendlyId
  friendly_id :name, use: :slugged
  friendly_id_config.treat_numeric_as_conflict = true
end

# Results:
Product.create(name: "123")     # slug: "123-f9f3789a-daec-4156-af1d-fab81aa16ee5"
Product.create(name: "abc123")  # slug: "abc123" (unchanged)

Testing Done

  • All existing tests pass
    • Verified backward compatibility (default behavior unchanged)
  • Added comprehensive test coverage for new functionality
    • Tests cover edge cases: zero, large numbers, alphanumeric combinations
    • Verified UUID conflict resolution works for multiple numeric slugs

Deploy Notes

  • No breaking changes: This is a new opt-in configuration option
  • No migration required: Uses existing slug storage and UUID conflict resolution
  • Safe to deploy: Feature is disabled by default, maintaining all existing behavior
  • Rollback safe: Simply remove configuration option to disable

@oehlschl
Copy link
Contributor Author

oehlschl commented Oct 4, 2025

@parndt I know there's not a ton of active development on friendly_id now, but any concerns with something like this? Thanks in advance.

@parndt
Copy link
Collaborator

parndt commented Oct 14, 2025

Thanks @oehlschl I think this seems fine to support. Is it possible to add to the changelog and add some docs around it for those using slugged so that people know it's an option (without reading the source code)?

@oehlschl
Copy link
Contributor Author

Yes, will follow up with the additional changes tonight; thanks @parndt!

@oehlschl
Copy link
Contributor Author

@parndt I added Guide documentation, and this change to the changelog (under Unreleased). Also updated the Int casting (will comment inline); please let me know if you need anything else. Thanks!

@parndt parndt changed the title Add treat_numeric_as_conflict option to prevent ambiguous numeric slugs Add treat_numeric_as_conflict option to prevent ambiguous numeric slugs Oct 16, 2025
@oehlschl
Copy link
Contributor Author

@parndt please let me know if you need anything else here, thanks!

@parndt parndt merged commit db7f702 into norman:master Oct 30, 2025
42 checks passed
@oehlschl oehlschl deleted the feature/treat-numeric-as-conflict branch November 12, 2025 05:22
@oehlschl
Copy link
Contributor Author

Pardon the ping @parndt, but would you please cut a new release when you can? Thanks!

@parndt
Copy link
Collaborator

parndt commented Nov 25, 2025

@oehlschl I will work on it; I've been meaning to set up trusted publishing for a while..

@parndt
Copy link
Collaborator

parndt commented Dec 6, 2025

@oehlschl after much ado with rubygems publishing, we have version 5.6.0!

@fschwahn
Copy link
Contributor

fschwahn commented Dec 8, 2025

@oehlschl Thanks for this - we had some custom code to deal with this, which I can now drop!

@oehlschl
Copy link
Contributor Author

oehlschl commented Dec 9, 2025

Glad to hear it! Thanks all. Upgrading the gem and removing some of our own custom code now too.

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.

3 participants