2010-01-15 15 views
5

我正在开发一个Rails应用程序,默认情况下会将用户帐户设置为他们选择的子域。作为选项,他们将能够将自己的完整域映射到他们的帐户。如何将完整域映射到基于子域的Rails应用程序帐户?

到目前为止,这是我如何设置的东西。我使用subdomain-fu供电路由:

# routes.rb 
map.with_options :conditions => {:subdomain => true} do |app| 
    app.resources # User's application routes are all mapped here 
end 

map.with_options :conditions => {:subdomain => false} do |www| 
    www.resources # Public-facing sales website routes are mapped here 
end 

除此之外,我使用的是method described here获得被访问的帐户,通过子域或全域:

before_filter :set_current_account 

def set_current_account 
    if request.host.ends_with? current_domain 
    # via subdomain 
    @current_club = Club.find_by_subdomain(current_subdomain) 
    else 
    # via full domain 
    @current_club = Club.find_by_mapped_domain(request.host) 
    end 
end 

我没有已经远远落后于构建这个过程,但已经可以看到我将遇到路由问题。如果request.host是一些random.com域,那么subdomain-fu不会路由适当的路线?

我假设这不是一个不寻常的问题,所以任何人都可以分享他们如何解决这个问题,或者我将如何配置我的路线去做我需要的东西?

回答

2

我遇到了这个问题,试图在单个应用程序中做太多。你会开始在非常奇怪的地方做你不应该的条件。我决定将2个独立的Rails应用程序的通配符域指向用户的应用程序,然后将www.domain.comdomain.com指向公共端。我知道这并不能直接“回答”你的问题。

小码味那里,我可以帮你解决,如果您添加到该方法的顶部:

return @current_club if defined?(@current_club) 

它不会让查询中的每个尝试访问@current_club时间,它将返回你已经返回的结果。

+0

谢谢您的回答。在试用另一个解决方案后,我得出结论,你是对的,为了简单起见,最好的办法是将其分成两个应用程序,并取消subdomain-fu。 – aaronrussell 2010-01-16 15:47:40

3

您可以编写一个Rack中间件,在将域打入Rails应用程序之前将其转换为子域。

class AccountDetector 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    account = Club.find_by_mapped_domain(env["HTTP_HOST"]) 
    if account 
     env["HTTP_HOST"] = "#{account.subdomain}.yourdomain.com" 
    end 

    @app.call(env) 
    end 
end 

然后添加到environment.rb

config.middleware.use AccountDetector 
+0

谢谢。我喜欢这个答案,所以做了一些测试。您的中间件脚本运行良好,但不幸的是,它会在会话中使用一些奇怪的连锁效应(使用Authlogic)。 我决定 - 不情愿 - 将应用程序分成两个独立的应用程序。 – aaronrussell 2010-01-16 15:45:12