0

我正在学习Sinatra (1.3.2) 并选择使用DataMapper (1.2.0) 作为 ORM 和内存中的SQLite (1.3.6) DB 来启动。和
两个模型共享大多数属性,因此我考虑在 DataMapper 中为 STI(单表继承)声明一个模型。阅读文档,多亏了Types::Discriminator,这似乎是小菜一碟。BooksDownloads

我将所有常见的抽象为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

按照示例,我认为它就像指定需要扩展的内容一样简单:

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 (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 必须有一个有效的键

我通过添加include DataMapper::Resource两个Bookand来解决这个问题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:,查询: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:我看过

但我仍然有这个问题。

4

1 回答 1

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
于 2012-12-13T16:33:36.313 回答