 davidsmindThe Eye's MindPremium join:2001-07-04 Canada | *Rails Beginner* Txt file upload to filesystem + DBHello all. I'm having some difficulty with the way that rails handles database writes vs. writes to hard drive. I can get my code to work to upload to the database, and to upload to the hard drive, but not both. I've tried replacing "after_save :store_doc" with just a direct call to the store_doc method, but that doesn't seem to work.
Can someone explain to me why this is? Without recommending a module to handle this, can someone guide me through writing a model that can accept a text upload, process the text into a DB and also write the file to a directory?
class Document < ActiveRecord::Base
attr_accessible :body, :extension, :filename, :upload
def upload=(incoming_file)
unless incoming_file.blank?
@incoming_file = incoming_file
self.filename = incoming_file.original_filename
self.extension = incoming_file.original_filename.split('.').last.downcase
if self.extension == 'txt'
self.body = incoming_file.read
else
self.body = 'wrong file type for direct uploading'
end
end
end
# def filename=(new_filename)
# write_attribute("filename", sanitize_filename(new_filename))
# end
# File.join is a cross-platform way of joining directories;
# we could have written "#{Rails.root}/public/doc_store"
DOC_STORE = File.join Rails.root, 'public', 'doc_store'
# where to write the first file to
def document_filename
File.join DOC_STORE, "#{id}.#{extension}"
end
# where to write the txt file to
def document_txtfilenamehas_document
File.join DOC_STORE, "#{id}.txt"
end
# return a path we can use in HTML for the docfile
def document_html_path
"/doc_store/#{id}.#{extension}"
end
# if a doc file exists, then we has a docfile
def has_document?
File.exists? document_filename
end
after_save :store_doc
private
def store_doc
logger.info "NOW inside store_doc"
if @incoming_file
#make the DOCSTORE dir if it doesn't already exist
FileUtils.mkdir_p DOC_STORE
#write out the data to the file
logger.info "write out the data to the file"
File.open(document_filename, 'wb') do |f|
f.write(@incoming_file.read)
end
# @incoming_file = nil
end
end
end
|
 davidsmindThe Eye's MindPremium join:2001-07-04 Canada | Keep in mind, with the above code, If I upload anything that ISNT a txt file, it gets saved to the hard drive no problem. |
 cdruGo ColtsPremium,MVM join:2003-05-14 Fort Wayne, IN kudos:7 | reply to davidsmind I don't do rails, however I think your problem is likely on line 57. incoming_file.read likely act like a stream reader. Once you've read it in, you can't go back. So the data gets passed on to f.write, but then you no longer have a handle on the data to read/save it again.
Try reading the file into a local variable, then saving the local variable's data to disk and/or the database. This does have the negative consequence of increasing memory requirements of your program to that of the size of the file you are uploading twice (one for uploaded file buffer, one for the variable. If they are small files probably not an issue. Large files it could be. |