DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
Home-brewed File Upload In Ruby On Rails
Most of this comes from others' work, but I was able to tool it to my needs and fix some bugs. All of these lines go in the model, which for me has a :file and :content_type attributes. :file stores the complete path to the uploaded file. Be sure to change the string in path_to_file to the place where you want files stored, and that proper permissions are set on that path. Also, sanitize_filename doesn't HAVE to be a private method -- make it public if you want.
### Model ###
def file=(uploaded_file)
@uploaded_file = uploaded_file
@filename = sanitize_filename(@uploaded_file.original_filename)
write_attribute("content_type", @uploaded_file.content_type)
end
def after_create
if !File.exists?(File.dirname(path_to_file))
Dir.mkdir(File.dirname(path_to_file))
end
if @uploaded_file.instance_of?(Tempfile)
FileUtils.copy(@uploaded_file.local_path, path_to_file)
else
File.open(self.path_to_file, "wb") { |f| f.write(@uploaded_file.read) }
end
write_attribute("file", path_to_file)
end
def after_destroy
if File.exists?(self.file)
File.delete(self.file)
Dir.rmdir(File.dirname(self.file))
end
end
def path_to_file
File.expand_path("#{RAILS_ROOT}/upload/#{self.id}/#{@filename}")
end
private
def sanitize_filename(file_name)
# get only the filename, not the whole path (from IE)
just_filename = File.basename(file_name)
# replace all none alphanumeric, underscore or perioids with underscore
just_filename.gsub(/[^\w\.\_]/,'_')
end
### View ###
...
<input type="file" name="model[file]" />
...






Comments
karel zeman replied on Thu, 2009/01/15 - 5:33am
Snippets Manager replied on Thu, 2007/04/26 - 7:07pm
Snippets Manager replied on Wed, 2006/03/29 - 10:25pm
Snippets Manager replied on Mon, 2006/09/04 - 11:34pm
class SingleFile < ActiveRecord::Base def file=(uploaded_file) @uploaded_file = uploaded_file @filename = sanitize_filename(@uploaded_file.original_filename) write_attribute(:content_type, @uploaded_file.content_type) end def after_create if !File.exists?(File.dirname(self.path)) FileUtils.mkdir_p(File.dirname(self.path)) end if @uploaded_file.instance_of?(Tempfile) FileUtils.copy(@uploaded_file.local_path, self.path) else File.open(self.path, "wb") { |f| f.write(@uploaded_file.read) } end write_attribute(:file, self.simple_path) self.save end def after_destroy if File.exists?(self.file) File.delete(self.file) Dir.rmdir(File.dirname(self.file)) end end def simple_path "#{self.id}/#{@filename}" end def path File.expand_path("#{RAILS_ROOT}/public/files/#{self.id}/#{@filename}") end private def sanitize_filename(file_name) # get only the filename, not the whole path (from IE) just_filename = File.basename(file_name) # replace all none alphanumeric, underscore or perioids with underscore just_filename.gsub(/[^\w\.\_]/,'_') end endSnippets Manager replied on Sun, 2006/04/16 - 5:07am
Snippets Manager replied on Thu, 2006/03/30 - 8:44am
self.content_type = @uploaded_file.content_type self.file = path_to_file