我正在学习 Sinatra (1.3.2)并选择使用 DataMapper (1.2.0)作为ORM和内存 SQLite (1.3.6)DB开始。
两个模型Books
和Downloads
共享大多数属性,因此我研究了在DataMapper中声明STI(单表继承)的模型。阅读the docs,感谢Types::Discriminator,这似乎是小菜一碟。
我将所有常见问题抽象为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:重复列名:id (代码:1,sql state :, query:ALTER TABLE“ downloadable_resources ”ADD COLUMN“id”INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,uri:sqlite3 :: memory:?scheme = sqlite&amp; user =&amp; password =&amp; host =&amp; port =&amp; query =&amp; fragment =&amp; adapter = sqlite3&amp; path =:memory: )
删除id时产生另一个(明显的)错误:
DataMapper :: IncompleteModelError:DownloadableResource必须有一个有效的密钥
我通过向include DataMapper::Resource
和Book
添加Download
来解决这个问题,然后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:重复列名:id (代码:1,sql state :, query:ALTER TABLE“ books ”ADD COLUMN“id”INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,uri:sqlite3 :: memory:?scheme = sqlite&amp; user =&amp; password =&amp; host =&amp; port =&amp; query =&amp; fragment =&amp; adapter = sqlite3&amp; path =:memory: )
开始觉得我要进入圈子,在DataMapper中实现单表继承的正确方法是什么?
PS:我看过了
但我仍有这个问题。
答案 0 :(得分: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