我在Rails中使用DataMapper,替换ActiveRecord并尝试进行单表继承。问题是,sqlite3似乎正在读取我所有的继承表,因此在尝试在ruby中创建该表的实例时会出现一些奇怪的错误。
我正在使用模型ServerFile来表示我想要在我的数据库中实例化的任何上传或通用文件。我有另一个模型,上传,它扩展了它并代表用户的上传。我还有两个模型,从ServerFile,Thumbnail和UploadThumbnail延伸,代表相应的上传缩略图和缩略图。
当我尝试创建一个像这样的上传实例时,我一直得到的错误是DataObjects::IntegrityError (server_files.upload_id may not be NULL)
:
upload = Upload.new(
filename: uploaded_io.original_filename,
path: path.to_s,
content_type: uploaded_io.content_type,
token: rand_token())
upload.member = @member
upload.title = params[:title]
upload.description = params[:description]
upload.save
这是我的模特:
class ServerFile
include DataMapper::Resource
property :id, Serial
property :token, String, unique_index: true
property :filename, String
property :path, Text, unique: true
property :content_type, Text, length: 5..200
property :type, Discriminator
property :created_on, Date
property :created_at, DateTime
property :updated_on, Date
property :updated_at, DateTime
end
class Upload < ServerFile
property :title, String
property :description, Text
has n, :topics, through: Resource
has n, :subjects, through: Resource
has n, :downloads
has n, :comments, 'UploadComment'
has n, :ratings, 'UploadRating'
belongs_to :member
has 1, :thumbnail, 'UploadThumbnail', required: false
end
class Thumbnail < ServerFile
@@IMAGE_EXTENSIONS = [:'png', :'jpg', :'jpeg', :'gif', :'svg', :'cgm']
validates_with_method :filename, :is_valid_image?
def is_valid_image?
@@IMAGE_EXTENSIONS.each do |ext|
return true if /[\w\d\.\_\-]+\.#{ext.to_s}/ =~ @filename
end
[false, 'Invalide image type.']
end
end
class UploadThumbnail < Thumbnail
belongs_to :upload
end
这是我的表的sqlite架构&#39; server_files&#39; (顺便说一句,当我列出我的表格时,&#39;上传内容并未列在其中):
sqlite> .schema server_files
CREATE TABLE "server_files" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "token" VARCHAR(50), "filename" VARCHAR(50), "path" TEXT, "content_type" TEXT, "type" VARCHAR NOT NULL, "created_on" DATE, "created_at" TIMESTAMP, "updated_on" DATE, "updated_at" TIMESTAMP, "title" VARCHAR(50), "description" TEXT, "member_id" INTEGER NOT NULL, "upload_id" INTEGER NOT NULL);
CREATE UNIQUE INDEX "unique_server_files_path" ON "server_files" ("path");
CREATE UNIQUE INDEX "unique_server_files_token" ON "server_files" ("token");
答案 0 :(得分:0)
upload_id
表上不需要server_files
列。因为Upload
继承自ServerFile
,所以这基本上是自我指涉的。模型成功保存后,类型为type
的列Discriminator
将在数据库中设置为Upload
。话虽这么说,如果你想设置一个自定义的upload_id,你可以用这样的回调来做:
before :create, :generate_upload_id
def generate_upload_id
generated_upload_id = <do something>
attribute_set(:upload_id, generated_upload_id) unless upload_id
end
否则,只需编写一个从server_files表中删除upload_id列的迁移
答案 1 :(得分:0)
DataMapper出于某种原因只是不喜欢我的超类ServerFile。当我把它分解时,它完美无缺! (:
class Upload < ServerFile
include DataMapper::Resource
property :id, Serial
property :token, String, unique_index: true
property :filename, String
property :path, Text, unique: true
property :content_type, Text, length: 5..200
property :created_on, Date
property :created_at, DateTime
property :updated_on, Date
property :updated_at, DateTime
property :title, String
property :description, Text
has n, :topics, through: Resource
has n, :subjects, through: Resource
has n, :downloads
has n, :comments, 'UploadComment'
has n, :ratings, 'UploadRating'
belongs_to :member
has 1, :thumbnail, 'UploadThumbnail', required: false
end
class Thumbnail < ServerFile
include DataMapper::Resource
property :id, Serial
property :token, String, unique_index: true
property :filename, String
property :path, Text, unique: true
property :content_type, Text, length: 5..200
property :type, Discriminator
property :created_on, Date
property :created_at, DateTime
property :updated_on, Date
property :updated_at, DateTime
@@IMAGE_EXTENSIONS = [:'png', :'jpg', :'jpeg', :'gif', :'svg', :'cgm']
validates_with_method :filename, :is_valid_image?
def is_valid_image?
@@IMAGE_EXTENSIONS.each do |ext|
return true if /[\w\d\.\_\-]+\.#{ext.to_s}/ =~ @filename
end
[false, 'Invalide image type.']
end
end
class UploadThumbnail < Thumbnail
belongs_to :upload
end