私はサブドメインを使って独立したアカウントサイトを隔離するRails(現在は2.3.4)アプリを開発中です。明確にするために、foo.mysite.comはfooアカウントのコンテンツを表示し、bar.mysite.comはバーのコンテンツを表示する必要があります。Rails:サブドメインに基づいてクエリをスコープするベストプラクティス?
すべてのモデルクエリが現在のサブドメインにスコープされるようにするにはどうすればよいですか?例えば
は、私のコントローラの一つは次のようになります。
@page = @global_organization.pages.find_by_id(params[:id])
(@global_organization
注サブドメイン府を経由してapplication_controllerに設定されている。) 私が希望している場合は、何かのように:
@page = Page.find_by_id(params[:id])
Pageモデルの検索対象は、自動的に適切な組織に限定されます。私はこのようなdefault_scopeディレクティブを使用して試してみた:グローバルアクセスのための組織のIDへ:[組織]だけに注目することは、再び
class Page < ActiveRecord::Base
default_scope :conditions => "organization_id = #{Thread.current[:organization]}"
# yadda yadda
end
((ページモデルで)、同じapplication_controllerはThread.currentを設定します。 )このアプローチの問題は、デフォルトのスコープが最初の要求に設定され、後続の要求が異なるサブドメインに変更されないことです。
これまでに三の見かけソリューション:各サブドメインの
1を使用する別のバーチャルホストだけ(mod_railsを使って)、サブドメインごとにアプリの異なるインスタンスを実行します。このアプローチは、このアプリケーションのためにスケーラブルではありません。
2上記の元のコントローラの方法を使用してください。残念ながら、アプリにはかなりの数のモデルがあり、モデルの多くは組織から削除された結合であるため、この表記法はすぐに面倒になります。悪化するのは、開発者が制限を覚えて適用したり、重大なセキュリティ上の問題を引き起こすことを積極的に要求することです。
3 before_filterを使用して、各リクエストのモデルのデフォルトスコープをリセットします。ここでのパフォーマンスのヒットや、reqeustごとに更新するモデルを選択する最良の方法については不明です。
思考?私が行方不明の他の解決策?これは、ベストプラクティスでなければならない共通の問題であるようです。すべての入力は、ありがとう!
ありがとう!実際にそのコードをテストしましたか?私はアプリで試してみましたが、ラムダが実際に各検索で評価されていることを確認できましたが、default_scopeは戻り値を適用しません。出力SQLを見てみると、:条件は単に無視されるようです。私はまだデバッガを起動することができませんでしたが、それ以外のさまざまな理由で、復旧してすぐにピークに達します。 なぜ機能しないのでしょうか? – qfinder
正直なところ、内部サーバがどのようにスレッドを使用しているのか分かりません。そのため、モデルでは 'Thread.current [:organization]'が働いていると思いました。しかし、条件が無視される理由を説明できるかどうかはわかりません。基本的には、organazation_id = nilを探すためのデフォルトスコープを定義しています。 – EmFi
さらなる調査の結果、これはまだ機能しないようです。パッチはありますが、YMMV:https://rails.lighthouseapp.com/projects/8994/tickets/1812-default_scope-cant-take-procs – EmFi