2012-12-30 12 views
11

私は私の目標は、DownloadableResourceモデルから共通の属性を継承することで、多くの属性を共有ブックダウンロードモデルを持っています。
STIを見ていたが、私が代わりにabstract base model class道を行ってきました:の実装抽象ベースモデルクラス、レールウェイ™

  • モデル:

    class DownloadableResource < ActiveRecord::Base 
        self.abstract_class = true 
    
        attr_accessible :title, :url, :description, :active, :position 
        validates :title, :url, :description, presence: true 
        scope :active, where(active: true).order(:position) 
    end 
    
    class Book < DownloadableResource 
        attr_accessible :cover_url, :authors 
        validates :cover_url, :authors, presence: true 
    end 
    
    class Download < DownloadableResource 
        attr_accessible :icon_url 
        validates :icon_url, presence: true 
    end 
    
  • 移行:移行後

    class CreateDownloadableResources < ActiveRecord::Migration 
        def change 
        create_table :downloadable_resources do |t| 
         t.string :title 
         t.string :url 
         t.text  :description 
         t.boolean :active,  default: false 
         t.integer :position 
         t.timestamps 
        end 
        end 
    end 
    
    class CreateBooks < ActiveRecord::Migration 
        def change 
        create_table :books do |t| 
         t.string :cover_url 
         t.string :authors 
         t.timestamps 
        end 
        end 
    end 
    
    class CreateDownloads < ActiveRecord::Migration 
        def change 
        create_table :downloads do |t| 
         t.string :icon_url 
         t.timestamps 
        end 
        end 
    end 
    

を、ときに私結果が遠い新しい帳を作成する予想:

> Book.new 
=> #<Book id: nil, cover_url: nil, authors: nil, created_at: nil, updated_at: nil> 

誰かがActiveRecordのモデルが異なるデータベーステーブルに永続化することはまだinheritanceを介して共通のコードを共有することができるように抽象ベースモデルクラスの技術を実装する方法にはいくつかの光を当てるていただけますか?

+0

一方向は継承ではなく合成です。いくつかの例:http://rails-bestpractices.com/posts/17-extract-into-module – VadimAlekseev

+0

2つの同様に構造化されたテーブルを使用する場合でも、少なくともすべての一意のフィールドだけを持つテーブルを作成してから '[:books、:downloads] .each do | table | change_tableテーブルdo | t | t.text:description #... end end' – Janosch

答えて

9

モデルを抽象として宣言することで、実際には基礎となるテーブルがなく、サブクラス化を許可したいと言っています。それは意味:

  • あなたはdownloadable_resourcesテーブル
  • Book.table_nameがbooks代わりのdownloadable_resources

@Finbarrは、すでに述べたように、これはまた、両方のBookDownloadモデルが必要であることを意味を出力する必要はありません。すべての属性をテーブルに入れる

実際には、これは実際には何が役に立ちますか?私の意見ではあまりありません。バリデーション、スコープなどを共有することができますが、カスタムモジュールを組み込むことで、バリデーションやスコープのすべてをより簡単に達成できます。

あなたの問題を解決するには、おそらく別の方法を使用します。自己完結型のDownloadableContentという別のモデルを作成します。これには検証が含まれ、テーブルにはすべての属性が含まれます。そして最後に、BookDownloadのモデルは、DownloadableContentモデルとの関係で多形has_oneを持つでしょう。

あなたはSTIのアプローチに行くことができますが、私は通常、すべてのカスタム属性を混在させたくありません。

5

この場合、downloadable_resourcesテーブルはありません。あなたの書籍とダウンロードテーブルの両方に、必要なすべてのフィールドを宣言する必要があります。

+2

なぜですか?このケースを継承に適さないものは何ですか?そして、それが継承する価値があるときとそうでないときを決める方法は? –

関連する問題