2016-05-15 14 views
2

質問の名前空間が含まれていますActiveRecordのモデル「タイプ」列には、関連するモデル

関連型の列を照会/格納しながら、私は関連クラスの名前空間を含まないためにはActiveRecordを伝えることができますどのように?

物事の現在の状態:

は、以下のクラス定義を考えてみましょう:

class PageTemplateA < ActiveRecord::Base 
    has_many :type_a_pages, :as => :pageable, :class_name => 'TypeAPage', :inverse_of => :pageable 
end 

##### The following class is implemented through STI. 
class TypeAPage < Page 
    belongs_to :pageable, :class_name => 'PageTemplateA', :inverse_of => :type_a_page 
end 

class Page < ActiveRecord::Base 
    belongs_to :pageable, :polymorphic => true 
end 

要約すると:

  • TypeAPagepages、データベーステーブルにSTIを介して実装されます。
  • TypeAPage私が作りたいの変化多型会合を介しPageTemplateAに関連付けられている(PageTemplateAに関連付けられているときpages.pageable_typePageTemplateAある)

されています。私はに上記のすべてのモデルを移動したい

を新しい名前空間、たとえば、PagesEnginePageTemplateAの私の定義は次のようになります:

module PagesEngine 
    class PageTemplateA < ActiveRecord::Base 
    has_many :type_a_pages, :as => :pageable, :class_name => 'TypeAPage', :inverse_of => :pageable 
    end 
end 

を除き、ActiveRecordはTypeAPagepageable_typePagesEngine::PageTemplateAと解釈します。

ActiveRecordに名前空間を含めないように指示するには、PagesEngine::PageTemplateAではなくPageTemplateApageable_typeを解決しますか?

答えて

0

それぞれのクラスの型のカラム名上書きするself.sti_nameを使用して:あなたは、次のブログ記事に便利を見つけるかもしれない

module PagesEngine 
    class PageTemplateA < ActiveRecord::Base 
    def self.sti_name 
     "PageTemplateA" 
    end 
    end 
end 

を:多型の関係を保持しているモデルの場合https://lorefnon.me/2014/07/27/optimizing-sti-columns.html

+0

あなたのお返事ありがとうございます、アンソニー。 しかし、この場合、 'PageTemplateA'に実装されたSTIはありません。これは実際には 'TypeAPage'にあります。 – progfan

2

を、することができますself.store_full_sti_class = falseを設定するか、store_full_sti_classをfalseに設定する抽象モデルから継承します。

module PagesEngine 
    class Page < Base 
    # self.store_full_sti_class = false 
    belongs_to :pageable, polymorphic: true 
    end 

    class TypeAPage < Page 
    belongs_to :pageable, 
       class_name: 'PageTemplateA', 
       inverse_of: :type_a_pages 
    end 
end 

型カラム(pageable_type)関連モデル(PagesEngine :: PageTemplateA)と一致するが、名前空間を持たないとの明示的範囲関係(type_as_pages)。

module PagesEngine 
    class PageTemplateA < Base 
    has_many :type_a_pages, 
      -> { where(pageable_type: 'PageTemplateA') }, 
      foreign_key: :pageable_id, 
      inverse_of: :pageable 
    end 
end 

は、最後にメソッドをオーバーライドして、belongs_toのアクティブレコードは、ポリモーフィック協会に属してカスタマイズします。

module PagesEngine 
    class Base < ActiveRecord::Base 
    self.abstract_class = true 
    self.store_full_sti_class = false 

    def self.belongs_to(name, scope = nil, options = {}) 
     super(name, scope, options).tap do |hash| 
     reflection = hash[name.to_s] 
     def reflection.association_class 
      if polymorphic? 
      BelongsToPolymorphicAssociation 
      else 
      super 
      end 
     end unless store_full_sti_class 
     end 
    end 
    end 

    class BelongsToPolymorphicAssociation < ActiveRecord::Associations::BelongsToPolymorphicAssociation 
    def klass 
     type = owner[reflection.foreign_type] 
     type.presence && PagesEngine.const_get(type) 
    end 
    end 
end 
関連する問題