0

我學習西納特拉(1.3.2),並選擇使用的DataMapper(1.2.0)作爲ORM和內存的SQLite(1.3.6)DB啓動。
兩個模型BooksDownloads共享大多數屬性,因此我研究了DataMapper中的STI(單表繼承)的聲明模型。閱讀the docs,這似乎是小菜一碟,感謝Types::Discriminator如何:DataMapper中的單表繼承?

我抽象所有常見的爲DownloadableResource

class DownloadableResource 
    include DataMapper::Resource 

    property :id,   Serial 
    property :created_at, DateTime 
    property :modified_at, DateTime 
    property :active,  Boolean, default: true 

    property :position,  Integer 

    property :title,  String, required: true 
    property :url,   URI,  required: true 
    property :description, Text,  required: true 

    property :type,   Discriminator 
end 

the example,我還以爲它只是那麼容易,因爲指定需要擴展的內容:

class Book < DownloadableResource 
    property :cover_url, URI 
    property :authors,  String, required: true, length: 255 
end 

class Download < DownloadableResource 
    property :icon_url,  URI 
end 

但這給了我以下錯誤:

DataObjects::SyntaxError: duplicate column name: id (code: 1, sql state: , query: ALTER TABLE "downloadable_resources" ADD COLUMN "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, uri: sqlite3::memory:?scheme=sqlite&user=&password=&host=&port=&query=&fragment=&adapter=sqlite3&path=:memory:)

同時去除ID,生成另一個(明顯)錯誤:

DataMapper::IncompleteModelError: DownloadableResource must have a key to be valid

我解決此得到了通過添加include DataMapper::ResourceBookDownload,然後Book需要的關鍵是有效的,現在看像這樣:

class Book < DownloadableResource 
    include DataMapper::Resource 

    property :id,   Serial 

    property :cover_url, URI 
    property :authors,  String, required: true, length: 255 
end 

同去的Download,但現在的問題是:

DataObjects::SyntaxError: duplicate column name: id (code: 1, sql state: , query: ALTER TABLE "books" ADD COLUMN "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, uri: sqlite3::memory:?scheme=sqlite&user=&password=&host=&port=&query=&fragment=&adapter=sqlite3&path=:memory:)

開始覺得我在圈子裏,在DataMapper中實現單表繼承的正確方法是什麼?


PS:我已經看過

,但我還是有這個問題。

回答

1

我會推薦這種方法:

module DownloadableResource 

    def self.included base 
    base.class_eval do 
     include DataMapper::Resource 

     property :created_at, DateTime 
     property :modified_at, DateTime 
     property :active,  base::Boolean, default: true 

     property :position,  Integer 

     property :title,  String, required: true 
     property :url,   base::URI,  required: true 
     property :description, base::Text,  required: true 

     property :type,   base::Discriminator 
    end 
    end 
end 

class Book 
    include DownloadableResource 
    property :id, Serial 
    # other properties 
end 

class Download 
    include DownloadableResource 
    property :id, Serial 
    # other properties 
end 
+1

'NameError:未初始化不斷DownloadableResource :: Boolean' –

+0

遺憾,錯過了,看到更新的答案 – 2012-12-13 16:58:43

+0

我做的完全一樣。但是當我添加'property:id,Serial'時,我得到了'DataMapper :: Property :: Serial:Class'的未定義方法\'屬性'。任何想法? –