开发者

Rails 3 routing based on context

开发者 https://www.devze.com 2023-01-17 21:38 出处:网络
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 o

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 p开发者_开发技巧roper 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.


Your approach seems like the best way to me. Anything else would be more cluttered and not very standard.

0

精彩评论

暂无评论...
验证码 换一张
取 消