I am trying to implement a "context" system similar to the one used by GitHub. For example, a Post may be created belonging either to the User or one of the Companies the User belongs to depending on whether to User is in the "User" context or a context that refers to one of the Companies.
As a part of this, I'd like to be able to do routing based on the user's current context. For example, if the User is in their own context, /dashboard
should route to users/show
, but if they are in the context for Company with ID 35, then /dashboard
should route to companies/35/dashboard
.
I could route /dashboard
to a special controller responsible for making such decisions, such as context#dashboard
which could then do a redirect_to
, but this doesn't feel quite right (perhaps because we're taking logic that the Rails routing module should be responsible for and moving it to a controller?)
What would be the proper way to solve this problem in Rails 3?
I finally found a solution to my problem that I like. This will use the URLs from my original question.
First, assume a session-stored Context
object that stores whether the user is in a "user" context or a "company" context. If the user is in a "company" context, then the ID of the company they're working as is in the object as well. We can get the context via a helper named get_context
and we can get the currently logged-in user via current_user
.
Now, we set up our routes as so:
config/routes.rb
:
MyApplication::Application.routes.draw do
get "dashboard" => "redirect", :user => "/users/show", :company => "/companies/:id/dashboard"
end
Now, app/controllers/redirect_controller.rb
:
class RedirectController < ApplicationController
def method_missing(method, *args)
user_url = params[:user]
company_url = params[:company]
context = get_context
case context.type
when :user
redirect_to user_url.gsub(":id", current_user.id.to_s)
when :company
redirect_to company_url.gsub(":id", context.id.to_s)
end
end
end
It's easy enough to keep the actual URLs for the redirect where they belong (in the routes.rb
file!) and that data is passed in to a DRY controller. I can even pass in the ID of the current context object in the route.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With