上传器产生有关应存储路径的列的错误

时间:2015-07-23 18:07:36

标签: ruby-on-rails ruby file-upload amazon-s3 carrierwave

图像模型与组织模型具有1:1的关联。在组织控制器中,create方法调用名为upload_file的图像模型方法。

def create
  @organization = Organization.new(new_params)
  if @organization.save
    Image.upload_file(@organization.id)
  end
end

upload_file方法使用carrierwave上传器将标准文件存储在Amazon S3存储桶中。为此,图像模型包括mount_uploader :file_name, ImageUploader

我的问题是如何为上传的文件创建一个Image实例?存储文件的路径应存储在Image模型的file_name列中。与图像关联的组织应存储在Image模型的organization_id列中。我怎样才能做到这一点?更具体地说,我应该为下面的模型方法添加什么代码? (另请参阅以下方法中的评论。

def self.upload_file(organization_id)
  file = 'app/assets/emptyfile.xml'
  uploader = ImageUploader.new
  uploader.store!(file)
  # Am I correct to assume that the previous line uploads the file using the uploader, but does not yet create an Image record?
  # If so, then perhaps the next line should be as follows?:
  # Image.create!(organization_id: organization_id, filename: file.public_url)
  # I made up "file.public_url". What would be the correct code to include the path that the uploader stored the image at (in my case an Amazon S3 bucket)?
end

目前在rails console我收到以下错误:

>> uploader = ImageUploader.new
=> #<ImageUploader:0x00000005d24f88 @model=nil, @mounted_as=nil, @fog_directory=nil>
>> file = 'app/assets/emptyfile.xml'
=> "app/assets/emptyfile.xml"
>> uploader.store!(file)
CarrierWave::FormNotMultipart: CarrierWave::FormNotMultipart
  from /usr/local/rvm/gems/ruby-2.2.1/gems/carrierwave-0.10.0/lib/carrierwave/uploader/cache.rb:120:in `cache!'
  etc.

1 个答案:

答案 0 :(得分:1)

您无需亲自调用上传器。 Carrierwave附带了一种机制,可以为您上传和存储AR模型:

u = Organization.new
u.image = params[:file] # Assign a file like this, or

# like this
File.open('somewhere') do |f|
  u.image = f
end

u.save!
u.image.url # => '/url/to/file.png'

u.image.current_path # => 'path/to/file.png'
u.image # => 'file.png'

然后你可以做

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
<img src="" id="elephant">
<script>
	(function () {
    // IndexedDB
    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB,
        IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction,
        dbVersion = 1.0;

    // Create/open database
    var request = indexedDB.open("elephantFiles", dbVersion),
        db,
        createObjectStore = function (dataBase) {
            // Create an objectStore
            console.log("Creating objectStore")
            dataBase.createObjectStore("elephants");
        },

        getImageFile = function () {
            // Create XHR
            var xhr = new XMLHttpRequest(),
                blob;
            xhr.open("GET", "/mobile/elephant.png", true);
            // Set the responseType to blob
            xhr.responseType = "blob";

            xhr.addEventListener("load", function () {
                if (xhr.status === 200) {
                    console.log("Image retrieved");
                    
                    // Blob as response
                    blob = xhr.response;
                    console.log("Blob:" + blob);

                    // Put the received blob into IndexedDB
                    putElephantInDb(blob);
                }
            }, false);
            // Send XHR
            xhr.send();
        },

        putElephantInDb = function (blob) {
            console.log("Putting elephants in IndexedDB");

            // Open a transaction to the database
            var transaction = db.transaction(["elephants"], "readwrite");

            // Put the blob into the dabase
            var put = transaction.objectStore("elephants").put(blob, "image");

            // Retrieve the file that was just stored
            transaction.objectStore("elephants").get("image").onsuccess = function (event) {
                var imgFile = event.target.result;
                console.log("Got elephant!" + imgFile);

                // Get window.URL object
                var URL = window.URL || window.webkitURL;

                // Create and revoke ObjectURL
                var imgURL = URL.createObjectURL(imgFile);

                // Set img src to ObjectURL
                var imgElephant = document.getElementById("elephant");
                imgElephant.setAttribute("src", imgURL);

                // Revoking ObjectURL
                //URL.revokeObjectURL(imgURL);
            };
        };

    request.onerror = function (event) {
        console.log("Error creating/accessing IndexedDB database");
    };

    request.onsuccess = function (event) {
        console.log("Success creating/accessing IndexedDB database");
        db = request.result;

        db.onerror = function (event) {
            console.log("Error creating/accessing IndexedDB database");
        };
        
        // Interim solution for Google Chrome to create an objectStore. Will be deprecated
        if (db.setVersion) {
            if (db.version != dbVersion) {
                var setVersion = db.setVersion(dbVersion);
                setVersion.onsuccess = function () {
                    createObjectStore(db);
                    getImageFile();
                };
            }
            else {
                getImageFile();
            }
        }
        else {
            getImageFile();
        }
    }
    
    // For future use. Currently only in latest Firefox versions
    request.onupgradeneeded = function (event) {
        createObjectStore(event.target.result);
    };
})();
</script>
</body>
</html>

请访问carrierwave README了解更多示例。