I’m working on a Rails application where I want to have nice looking URLs with slugs for regular users, but simple ID-based URLs in the admin area.
Right now I have this method in my model:
def to_param
"#{id}-#{title.parameterize}"
end
This creates pretty URLs like /posts/123-my-awesome-post
which is perfect for the public site. However, when I’m working in the admin section and editing records, things get messy because the slug changes when I update the title.
Is there a clean way to make Rails use just the regular ID (like /admin/posts/123
) when I’m in the admin namespace, but keep the slug format for everything else? I want to avoid the confusion that happens when editing records in the backend.
I ran into this same issue before. Here’s what worked for me: create separate controllers for admin stuff. Don’t mess with to_param
at all - just keep the slugged URLs for your public controllers and make dedicated admin controllers that use standard IDs. Your admin routes will automatically use regular IDs while public routes keep the pretty URLs. You can have all admin controllers inherit from a base admin controller to share common code. This kills the complexity of context-aware URL generation and makes routing way more predictable. Clean separation between frontend and backend without fighting Rails.
also, don’t forget to handle redirects properly! if someone hits an old slug, you might want to send them to the new URL without confusion. that way, the user experience stays smooth.
Interesting challenge! Have you tried overriding the to_param
method based on request context? Maybe check if you’re in an admin namespace? Also curious - when you edit titles, do existing bookmarks break too?