Skip to content

Override route helpers instead of to_param#17

Open
kanejamison wants to merge 1 commit intomainfrom
attempt-to-override-route-helpers-instead-of-to_param
Open

Override route helpers instead of to_param#17
kanejamison wants to merge 1 commit intomainfrom
attempt-to-override-route-helpers-instead-of-to_param

Conversation

@kanejamison
Copy link
Owner

Implements scoped path helper overrides for Bunko-managed collection routes, allowing ergonomic usage (blog_path(@post)) without affecting admin/CMS routes.

Problem

Previous Approach: Override to_param to return slug

  • ✅ Clean syntax everywhere: blog_path(@post), edit_post_path(@post)
  • ❌ Global override - affects ALL routes (admin, API, etc.)
  • ❌ Admin interfaces forced to use slugs instead of IDs
  • ❌ Slugs can change, making admin work less reliable

User Need:

  • Public collection routes should use slugs: /blog/my-post-slug
  • Admin/CMS routes should use IDs: /posts/123/edit
  • View helpers should be ergonomic: blog_path(@post) not blog_path(@post.slug)

Solution

Hijack only Bunko-controlled path helpers by dynamically overriding them at route-load time:

  # lib/bunko/helpers/collection_path_helpers.rb
  def blog_path(post_or_slug = nil, *args)
    if post_or_slug.respond_to?(:slug)
      super(post_or_slug.slug, *args)  # Extract slug
    else
      super(post_or_slug, *args)        # Pass through
    end
  end

Implementation

  1. Route Registration (lib/bunko/routing/mapper_methods.rb)
    - bunko_collection :blog registers "blog" with Configuration
  2. Configuration Tracking (lib/bunko/configuration.rb)
    - Maintains array of collection path helpers to override
  3. Dynamic Helper Generation (lib/bunko/helpers/collection_path_helpers.rb)
    - Generates _path and _url override methods for each registered collection
    - Uses define_method to create helpers at runtime
  4. Railtie Integration (lib/bunko/railtie.rb)
    - Installs helper overrides in config.after_initialize
    - Includes module in both ActionView and ActionController

Result

  # Collection views - ergonomic ✓
  blog_path(@post)          # → /blog/my-post-slug
  docs_path(@post)          # → /docs/my-post-slug

  # Admin views - reliable IDs ✓
  edit_post_path(@post)     # → /posts/123/edit
  admin_post_path(@post)    # → /admin/posts/123

  # Still flexible
  blog_path("custom-slug")  # → /blog/custom-slug
  blog_path                 # → /blog

Pros vs. Previous Approach

Current (Dynamic Helpers):

  • ✅ Scoped - only affects Bunko routes
  • ✅ Admin routes use reliable IDs
  • ✅ Ergonomic in collection views
  • ✅ Non-invasive - doesn't override to_param
  • ✅ Developers retain full control over admin interfaces
  • ⚠️ More complex implementation
  • ⚠️ Magic happens at route-load time (harder to debug)

Previous (to_param Override):

  • ✅ Simpler implementation
  • ✅ Consistent everywhere (always uses slugs)
  • ✅ Matches friendly_id pattern (widely understood)
  • ❌ Global override affects all routes
  • ❌ Admin forced to use slugs (less reliable)
  • ❌ More opinionated (violates Bunko's lightweight philosophy)

Files Changed

  • lib/bunko/configuration.rb - Add collection_path_helpers tracking
  • lib/bunko/routing/mapper_methods.rb - Register helpers during route definition
  • lib/bunko/helpers/collection_path_helpers.rb - New - Dynamic helper overrides
  • lib/bunko/railtie.rb - Install helpers after initialization
  • lib/bunko/models/post_methods.rb - Remove to_param override

Open Questions

  1. Complexity trade-off: Is the scoped approach worth the added complexity?
  2. Debugging: Helper overrides may be harder to trace than to_param
  3. Alternative: Should we just document that admin interfaces should use find_by(slug:) and keep the simpler to_param approach?

Recommendation

Consider reverting to to_param approach if:

  • Bunko users primarily use admin gems like Avo/ActiveAdmin (they handle slug lookups)
  • Simplicity > separation of concerns
  • friendly_id pattern is acceptable

Keep dynamic helpers if:

  • Admin reliability (ID-based) is critical
  • Users build custom admin interfaces
  • Minimal global impact is important

@kanejamison kanejamison force-pushed the attempt-to-override-route-helpers-instead-of-to_param branch from d714dbb to a775400 Compare November 14, 2025 04:17
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.

1 participant