Monday, February 8, 2010

Files upload without any plugins in ROR

There are lots of plugins available for upload files in ruby on rails.

* file_column plugin:
* attachment_fu
* flex_image
* upload_column
* and many more

Accoding to me, all these file are more useful for image uplaoding not other files like voice file, pdf and other.

So I made a defination which check following things and then upload a file on defined location.

1. File extension.

2. Mime type (require mime type plugin)

3. Size of the file

#Define basic things in enviornment/development.rb file
01.FILE_EXTENSIONS = [".wav",".mp3",".gsm",".pdf"] #Allowed file types
02.
03.FILE_TEMP_PATH="#{RAILS_ROOT}/public/temp/" #Where file is initialy uploaded
04.
05.FILE_MIME_EXTENSIONS =["audio/x-wav","audio/mpeg","audio/gsm","audio /x-gsm","application/pdf"] #Allowed file types
06.
07.FILE_ROOT_PATH= "#{RAILS_ROOT}/public/saved/" #Where file is uploaded permanently
08.
09.FILE_MAXIMUM_SIZE_FOR_FILE=1048576 #Maximum Size (1MB) define in bytes

#In model
01.before_save :save_file
02.
03.attr_accessor :file_data
04.
05.def get_filename
06.#define your rename file method
07.t = Time.now
08."file_#{t.strftime("%Y%m%d%H%M")}"
09.end
10.
11.def save_file
12.begin
13.# No update necessary
14.return true if self.file_data.blank?
15.filename = get_filename
16.return false if filename.nil?
17.
18.extension = File.extname(self.file_data.original_filename)
19.if extension.nil?
20.errors.add(:file_data,"Wrong Extension")
21.return false
22.end
23.
24.# Check if the FILE_TEMP_PATH is created, if not try to create
25.if !File.directory?(FILE_TEMP_PATH)
26.File.makedirs(FILE_TEMP_PATH)
27.end
28.
29.temp_source = File.join(FILE_TEMP_PATH, filename)
30.temp_source << extension
31.final_source = File.join(FILE_ROOT_PATH, filename)
32.final_source << extension
33.
34.File.open(temp_source, "wb") { |f| f.write(self.file_data.read)}
35.
36.size=File.size(temp_source)
37.extension = File.extname(temp_source)
38.mime_extension=File.mime_type?(temp_source)
39.if FILE_MIME_EXTENSIONS.include?(mime_extension) == false
40.logger.error("Trying to upload file with mime-type: #{mime_extension} ")
41.errors.add(:file_data,"Only wav, mp3,gsm and pdf files are allowed")
42.return false
43.end
44.if FILE_EXTENSIONS.include?(extension) == false
45.logger.error("Trying to upload file with extension: #{extension} ")
46.errors.add(:file_data,"File extension should be wav, mp3, gsm or pdf")
47.return false
48.end
49.if size > FILE_MAXIMUM_SIZE_FOR_FILE
50.logger.error("Trying to upload file with size: #{size} ")
51.errors.add(:file_data,"File should not be more than #{FILE_MAXIMUM_SIZE_FOR_FILE} bytes")
52.return false
53.end
54.if valid? #Upload in permanent folder
55.logger.error("#{self.errors.to_xml}")
56.self.file=filename
57.FileUtils.copy_file(temp_source,final_source)
58.FileUtils.rm(temp_source) if File.exists?(temp_source)
59.return true
60.else
61.errors.add(:file_data,"Invalid file format")
62.FileUtils.rm(temp_source) #Remove temp file
63.return false
64.end
65.rescue => e
66.logger.error(e)
67.errors.add(:file_data,"Invalid file format")
68.return false
69.end
70.
71.end

# In View form
1.<% form_for :obj_name,:html=>{:multipart=>true} do |f| %>
2.
3.<%= f.error_messages %>
4.
5.File: <%=f.file_field :file_data%>
6.<%= f.submit "Create" %>
7.
8.<% end %>