0

Rails で DataMapper を使用し、ActiveRecord を置き換えて、単一テーブルの継承を試みています。問題は、sqlite3 が継承したすべてのテーブルを奇妙に読み取っているように見えるため、Ruby でそのテーブルのインスタンスを作成しようとすると、奇妙なエラーが発生することです。

モデル ServerFile を使用して、データベースにインスタンス化するアップロード ファイルまたは汎用ファイルを表します。それを拡張し、ユーザーからのアップロードを表す別のモデル Upload があります。ServerFile、Thumbnail、および UploadThumbnail から拡張されたモデルがさらに 2 つあります。これらは、一般的な Thumbnail とアップロード用の Thumbnail をそれぞれ表します。

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

そして、これがテーブル「server_files」のsqliteスキーマです(ところで、テーブルをリストすると、「アップロード」はそれらの中にリストされません):

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");
4

2 に答える 2

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
于 2013-08-06T15:12:56.377 に答える
0

テーブルupload_idに列は必要ありません。から継承するserver_filesため、これは本質的に自己参照になります。モデルが正常に保存されると、タイプの列がデータベースに設定されます。そうは言っても、とにかくカスタムのupload_idを設定したい場合は、次のようなコールバックでそれを行うことができます:UploadServerFiletypeDiscriminatorUpload

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

于 2013-08-04T16:38:20.890 に答える