2013-08-04 34 views
0

我在Rails中使用DataMapper,取代ActiveRecord,並試圖做一些單表繼承。問題是,sqlite3似乎正在閱讀我所有的繼承表,這使我在嘗試在ruby中創建該表的實例時遇到了一些奇怪的錯誤。DataMapper w/Rails中的表不能繼承正確

我使用的一個模型,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模式對於表'server_files'(順便說一句,當我列出我的表時,'上傳'並未列在其中):

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

的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 
0

server_files表中不需要upload_id列。因爲Upload繼承自ServerFile,這基本上是自我指涉的。與Discriminator型列type將在數據庫中,當保存成功模式設置爲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列

來源:http://datamapper.org/docs/misc.html