簡體   English   中英

Rails:基於子域的查詢范圍的最佳實踐?

[英]Rails: best practice to scope queries based on subdomain?

我正在開發一個Rails(目前是2.3.4)應用程序,該應用程序利用子域來隔離獨立的帳戶站點。 要明確的是,我的意思是foo.mysite.com應該顯示foo帳戶的內容,bar.mysite.com應該顯示欄的內容。

確保所有模型查詢都限定在當前子域的最佳方法是什么?

例如,我的一個控制器看起來像:

@page = @global_organization.pages.find_by_id(params[:id])        

(注意@global_organization是通過subdomain-fu在application_controller中設置的。)當我想要的是:

@page = Page.find_by_id(params[:id])

Page模型找到的位置自動限定在正確的組織中。 我嘗試過使用default_scope指令,如下所示:(在Page模型中)

class Page < ActiveRecord::Base
  default_scope :conditions => "organization_id = #{Thread.current[:organization]}"
  # yadda yadda
end

(再次,請注意,相同的application_controller將Thread.current [:organization]設置為組織的全局訪問ID。)此方法的問題是默認范圍在第一個請求上設置,並且永遠不會在后續請求中更改不同的子域名。

到目前為止有三種明顯的解

1為每個子域使用單獨的vhost,並且每個子域只運行應用程序的不同實例(使用mod_rails)。 此方法不適用於此應用。

2使用上面的原始控制器方法。 不幸的是,應用程序中有相當多的模型,許多模型都是從組織中刪除的一些連接,因此這種表示法很快變得很麻煩。 更糟糕的是,這主動要求開發人員記住並應用限制或冒重大安全問題。

3使用before_filter重置每個請求的模型的默認范圍。 不確定此處的性能或如何最好地選擇要更新的模型。

思考? 我還缺少其他任何解決方案嗎? 這似乎是一個普遍的問題,必須有一個最佳實踐。 感謝所有投入,謝謝!

您是否嘗試過將default_scope定義為lambda 每次使用范圍時,都會評估定義選項的lambda位。

class Page < ActiveRecord::Base
  default_scope lambda do 
   {:conditions => "organization_id = #{Thread.current[:organization]}"}
  end
  # yadda yadda
end

它基本上是你的第三個選擇,通過與你之前的過濾魔法一起工作。 但它比那更具侵略性,可以使用Page模型中使用的每一個查找。

如果你想為所有模型使用這種行為,你可以將default_scope添加到ActiveRecord :: Base,但是你提到了一些是幾個連接。 因此,如果您使用此路線,則必須覆蓋這些模型中的默認范圍以解決連接問題。

這里要小心使用默認范圍,因為這會導致您產生錯誤的安全感,特別是在創建記錄時。

我總是用你的第一個例子來說明這一點:

@page = @go.pages.find(params[:id])

最大的原因是因為您還希望確保將此關聯應用於新記錄,因此您的新/創建操作將如下所示,確保它們適當地限定為父關聯:

# New
@page = @go.pages.new

# Create
@page = @go.pages.create(params[:page])

您可能更好的是為每個帳戶創建一個數據庫並根據子域切換數據庫連接

除了上面的鏈接,如果你有一個模型(在你的情況下是帳戶)你想使用默認數據庫,只需在模型中包含establish connection

class Account < ActiveRecord::Base

  # Always use shared database
  establish_connection  "shared_#{RAILS_ENV}".to_sym

我發現acts_as_tenant gem [ github ]非常適合這個功能。 它以最小的額外努力為您確定范圍,並且還使繞過范圍很難。

這是關於它的最初博客文章: http//www.rollcallapp.com/blog/2011/10/03/adding-multi-tenancy-to-your-rails-app-acts-as-tenant

我們在過去的兩年里一直在使用https://github.com/penguincoder/acts_as_restricted_subdomain ,但它只適用於Rails 2.3。

我們目前正在嘗試升級(和gemmify)插件以使用Rails 3.我很好奇你如何處理你的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM