我已经被困在这个问题上好几天了,似乎已经遇到了问题。我使用的是rails 4.1,angular 1.2.23和paperclip 4.1。我从许多类似问题的解决方案中抽样,但似乎都没有解决问题。
当我在doc模型中设置回形针附件时,我能够上传一个附件。但是,当我将附件与doc模型分开并为多个附件添加图像模型时,我无法使其工作。
以下是我正在使用的代码:
doc.rb
class Doc < ActiveRecord::Base
has_many :image, :dependent => :destroy
accepts_nested_attributes_for :image, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end
image.rb
class Image < ActiveRecord::Base
belongs_to :doc
has_attached_file :image, :styles => { :lrg => "700x700>", :med => "350x350>", :sml => "100x100>" }, :whiny => false,
:path => ":rails_root/public/system/:attachment/:id/:style/:filename",
:url => "/system/:attachment/:id/:style/:filename"
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
def image=(files = [])
files.each{|f| (@image ||= []) << image.create(image: f) }
end
end
这是我的控制器:
class DocsController < ApplicationController
skip_before_filter :verify_authenticity_token
def index
@docs = if params[:keywords]
Doc.where("title ilike ?", "%#{params[:keywords]}%")
else
[]
end
@items = Doc.all
end
def show
@doc = Doc.find(params[:id])
end
def create
if params[:imageData]
decode_image
@doc = Doc.new(@up)
else
@doc = Doc.new(params.require(:doc).permit(:id, :title, :parent, :info))
end
if @doc.save
render 'show', status: 201
else
render json: @doc.errors, status: :unprocessable_entity
Rails.logger.info @doc.errors
end
end
def update
doc = Doc.find(params[:id])
if params[:imageData]
decode_image
doc.update_attributes(@up)
else
doc.update_attributes(params.require(:doc).permit(:id, :title, :parent, :info))
end
head :no_content
end
def destroy
doc = Doc.find(params[:id])
doc.destroy
head :no_content
end
private
def doc_params
@up = params.require(:doc).permit(:id, :title, :parent, :info, image_attributes: [:_destroy, :id, :image])
end
def decode_image
@up = params.require(:doc).permit(:id, :title, :parent, :info, image_attributes: [:_destroy, :id, :image])
# decode base64 string
Rails.logger.info 'decoding now'
decoded_data = Base64.decode64(params[:imageData]) # json parameter set in directive scope
# create 'file' understandable by Paperclip
@data = StringIO.new(decoded_data)
@data.class_eval do
attr_accessor :content_type, :original_filename
end
# set file properties
@data.content_type = params[:imageContent] # json parameter set in directive scope
@data.original_filename = params[:imagePath] # json parameter set in directive scope
# update hash, I had to set @up to persist the hash so I can pass it for saving
# since set_params returns a new hash everytime it is called (and must be used to explicitly list which params are allowed otherwise it throws an exception)
@up[image_attributes: [:image]] = @data # image is the model attribute that is defined as an attachment using paperclip generator
end
end
这是我的上传指令使用angular:
angular.module('fileUpload', []) // using restangular is optional
.directive('uploadImage', function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
// listens on change event
elem.on('change', function() {
console.log('entered change function');
for (var i = 0; i < elem.length; i++) {
for (var x = 0; x < elem[i].files.length; x++) {
var file = elem[i].files[x];
// gathers file data (filename and type) to send in json
scope.doc.imageContent = file.type;
scope.doc.imagePath = file.name;
console.log(scope.doc.imagePath);
// converts file to binary string
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function (e) {
// retrieves the image data from the reader.readAsBinaryString method and stores as data
// calls the uploadImage method, which does a post or put request to server
scope.doc.imageData = btoa(e.target.result);
// updates scope
}
scope.uploadImage(scope.doc.imagePath);
scope.$apply();
}
};
});
},
controller: ['$scope', '$location', '$resource', function($scope, $location, $resource){
$scope.uploadImage = function (path) {
var Doc;
Doc = $resource('/docs/:docId', {
docId: "@id",
format: 'json'
}, {
'save': {
method: 'PUT'
},
'create': {
method: 'POST'
}
});
// if updating doc
console.log($scope.doc);
var onError;
onError = function(_httpResponse) {
return flash.error = "Something went wrong";
};
if ($scope.doc.id) {
$scope.doc.$save((function() {
$scope.docImageLink = baseUrl + $scope.doc.image_url;
}), onError);
} else {
console.log("create");
}
};
}]
};
});
最后,这是我的表格字段:
<input type="file" id="doc.image" name="doc.image" ng-model='doc.image' upload-image multiple/>
<img ng-src="{{userImageLink}}" ng-click="openFileWindow()" ng-class="{ hidden: !userImageLink}" >
<div class="drop-box" ng-click="openFileWindow()" ng-class=" {hidden: userImageLink}">
Add Image
</div>
当我提交包含多个附件的表单时,我在rails log中收到此错误:
ActiveRecord::UnknownAttributeError (unknown attribute: {:image_attributes=>[:image]}):
app/controllers/docs_controller.rb:21:in `create'
这是我的第一个主要的rails应用程序,所以任何帮助都会受到重视。我还可以提供所需的任何后续信息。
谢谢!