Rails 3でサブドメインを操作したすべての人がこの
スクリーンキャストを見たと思います。
この例に直面したときのタスクは、動的サブドメインといくつかの固定サブドメインを作成することでした。 ダイナミックは、モデルのいずれかのフィールドに対応する必要があります。 したがって、最終的なソリューションの条件が提示されました。
- 固定サブドメインまたはサブドメインのグループを指定する機能。
- ActiveRecordモデルからフィールドにスナップする機能。
- これをすべてroutes.rbに書き込む便利な構文。
実装
最初の段落を実装するために、上記の例を基礎として、サブドメイン名またはその配列を転送する機能により拡張しました。
サブドメイン/ base.rbmodule Subdomain class Base attr_accessor :subdomain def initialize(param = ["www"] ) @subdomains = case param.class.to_s when "String", "Symbol" [param] when "Array" param else [] end end def matches?(request) self.subdomain?( request ) && ( @subdomains.map {|i| i.to_s == request.subdomain }.include? true ) end protected def subdomain?(request) request.subdomain.present? and ( request.subdomain != "www" ) end end end
ここで説明することは何もないと思います。
次に、2番目の段落の実装の順番が来ました。
このクラスでは、一致をチェックするメソッドで、クラスのインスタンスがその名前で取得されます。 次に、テーブル内のサブドメインの存在を確認します。
サブドメイン/ active_record.rb class Subdomain::ActiveRecord < Subdomain::Base attr_reader :model attr_accessor :field def initialize(params) p = params.first @model = p[1] @field = p[0] end def matches?(request) obj = case @model.class when String @model.classify.constantize when Symbol @model.to_s.classify.constantize else @model end subdomain?(request) and ( obj.superclass == ActiveRecord::Base ) and obj.where(field.to_sym => request.subdomain).first.present? end end
そして3番目のステップは、
routes.rbでのルールの記述を単純化すること
でした 。 この例が提供するオプションを使用すると、非常にかさばるメモが表示され、一見しただけでははっきりしません。
constraints( Subdomain::ActiveRecord.new Site::User, :login ) do root :to => "main#index" end constraints( Subdomain::Base.new [:admin] ) do scope :module => "admin", :as => :admin do root :to => "main#index" end end
メソッドを追加するには、パスを担当するクラス、つまり
ActionDispatch :: Routing :: Mapperを展開する必要があります。
このため、アプリケーションのロードプロセス中にメインクラスと混合したモジュールが作成されました。
config / initializers / subdomain.rb ActionDispatch::Routing::Mapper.send(:include, Subdomain::Extension)
サブドメイン/ extension.rb module Subdomain module Extension def subdomain( sub, params = {} ) if params[:scope] scope :module => params[:scope].to_s, :as => params[:scope].to_sym do unscoped_subdomain( sub ) { yield } end else m = case sub.class.to_s when "Symbol", "String" sub.to_s when "Array" sub.first when "Hash" nil end if m.blank? or params.key?(:scope) unscoped_subdomain( sub ) { yield } else scope :module => m, :as => m.to_sym do unscoped_subdomain( sub ) { yield } end end end end def unscoped_subdomain( sub ) case sub.class.to_s when "Symbol", "String", "Array" constraints( Subdomain::Base.new sub ) { yield } when "Hash" p = sub.first inst = "subdomain/
その後、前述の設計は次のものに置き換えられました。
subdomain( :active_record => { :login => Site::user } ) do root :to => "main#index" end subdomain( :admin ) do root :to => "main#index" end
結果
結果は、サブドメインを操作するための非常に便利なインターフェイスです。
subdomain( "subdomain" ) do root :to => "main#index"
建設的な批判とアドバイスを歓迎します。 曲がったコードの場所を事前におaび申し上げます。
PS :ファイルは
アーカイブにあり
ます 。
PPS :構文の強調表示に関して、何らかの理由で最終バージョンではすべてがプレビューにあります。