Rails:基于子域的查询范围的最佳实践?

qfi*_*der 9 ruby-on-rails

我正在开发一个Rails(目前是2.3.4)应用程序,该应用程序利用子域来隔离独立的帐户站点.要明确的是,我的意思是foo.mysite.com应该显示foo帐户的内容,bar.mysite.com应该显示栏的内容.

确保所有模型查询都限定在当前子域的最佳方法是什么?

例如,我的一个控制器看起来像:

@page = @global_organization.pages.find_by_id(params[:id])        
Run Code Online (Sandbox Code Playgroud)

(注意@global_organization是通过subdomain-fu在application_controller中设置的.)当我喜欢的是:

@page = Page.find_by_id(params[:id])
Run Code Online (Sandbox Code Playgroud)

Page模型找到的位置自动限定在正确的组织中.我尝试过使用default_scope指令,如下所示:(在Page模型中)

class Page < ActiveRecord::Base
  default_scope :conditions => "organization_id = #{Thread.current[:organization]}"
  # yadda yadda
end
Run Code Online (Sandbox Code Playgroud)

(再次,请注意,相同的application_controller将Thread.current [:organization]设置为组织的全局访问ID.)此方法的问题是默认范围在第一个请求上设置,并且永远不会在后续请求中更改不同的子域名.

到目前为止有三种明显的解

1为每个子域使用单独的vhost,并且每个子域只运行应用程序的不同实例(使用mod_rails).此方法不适用于此应用.

2使用上面的原始控制器方法.不幸的是,应用程序中有相当多的模型,许多模型都是从组织中删除的一些连接,因此这种表示法很快变得很麻烦.更糟糕的是,这主动要求开发人员记住并应用限制或冒重大安全问题.

3使用before_filter重置每个请求的模型的默认范围.不确定此处的性能或如何最好地选择要更新的模型.

思考?我还缺少其他任何解决方案吗?这似乎是一个普遍的问题,必须有一个最佳实践.感谢所有投入,谢谢!

EmF*_*mFi 2

您是否尝试过定义default_scopea lambdalambda每次使用范围时都会评估定义选项的位。

class Page < ActiveRecord::Base
  default_scope lambda do 
   {:conditions => "organization_id = #{Thread.current[:organization]}"}
  end
  # yadda yadda
end
Run Code Online (Sandbox Code Playgroud)

它本质上是在做你的第三个选择,通过与你的过滤器魔法协同工作。但它比这更激进一点,会启动 Page 模型上使用的每一个发现。

如果您希望所有模型都具有这种行为,您可以将 default_scope 添加到 ActiveRecord::Base,但您提到了一些模型需要几个连接。因此,如果您采用此路线,则必须覆盖这些模型中的默认范围才能解决连接问题。


归档时间:

查看次数:

2862 次

最近记录:

12 年,8 月 前