I'm learning Sinatra (1.3.2) and chose to use DataMapper (1.2.0) as ORM and an in-memory SQLite (1.3.6) DB to start.
Two models, Books and Downloads, are sharing most attributes, so I looked into declaring a model for STI (Single Table Inheritance) in DataMapper. Reading the docs, this seems a piece of cake thanks to Types::Discriminator.
I abstracted all common ones into 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
Following the example, I thought it's just as easy as specifying what needs to be extended:
class Book < DownloadableResource
  property :cover_url,    URI
  property :authors,      String,   required: true, length: 255
end
and
class Download < DownloadableResource
  property :icon_url,     URI
end
but this was giving me the following error:
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:)
while removing the id generated another (obvious) error:
DataMapper::IncompleteModelError: DownloadableResource must have a key to be valid
I got around this by adding include DataMapper::Resource to both Book and Download, and then Book needed a key to be valid, now looking like this:
class Book < DownloadableResource
  include DataMapper::Resource
  property :id,           Serial
  property :cover_url,    URI
  property :authors,      String,   required: true, length: 255
end
Same goes for Download, but now the issue is:
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:)
Starting to feel like I'm going in circles, what's the proper way to implement Single Table Inheritance in DataMapper?
PS: I have looked at
but I still have this problem.