This should be a quick post. {"If", "I", "can", "help", "it!"}.reverse! = {"it!", "help", "can", "I", "If"}. =)
Well, there you have it. The simplicity of the reverse! method for arrays. This is especially great when you query the database for a group of records, then decide you need them in the reverse order. When might you actually need to do that? Well let me give you my example (and if anyone has a better way, let me kn0w):
@posts = Post.find(:all, :order => "id DESC", :limit => "25")
@posts.reverse!
In this situation I was pulling out the 25 of the newest posts (I ordered them by id descending - so the newest id would be at the top). Then before I printed the posts in the view I wanted to print the oldest at the top (like most message boards). So I just used the .reverse! method for arrays (you can read more about methods available to arrays by going to the Ruby Core Lib Reference).
Simple enough, so now on to the second part of this post - and perhaps the most enjoyable - a working Model that can help in simple file uploading. I may have already given snippets from this model, but I think it deserves a full feature:
class Upload < ActiveRecord::Base
def upload(file,directory="/your/directory/here")
@file = file
@directory = directory
@extension = get_extension(@file)
return save_file
end
def get_extension(file)
return file.original_filename.to_s.split(".")[1]
end
def get_original(file)
return file.original_filename.to_s
end
def save_file
if @file.path
@time_now = Time.now.to_i
FileUtils.mv(@file.path, Dir.getwd << @directory << @time_now.to_s << "." << @extension)
return @time_now.to_s << "." << @extension
else
return "File Not Uploaded"
end
end
end
Instead of explaining how everything works, let me just give you the rest of the picture and a quick example how I used it in my controller to save files.
My database table:
CREATE TABLE `uploads` (
`id` int(11) NOT NULL auto_increment,
`oldname` varchar(255) NOT NULL default '',
`newname` varchar(255) NOT NULL default '',
`directory` varchar(50) NOT NULL default '',
`user_id` varchar(50) NOT NULL default '',
PRIMARY KEY (`id`)
);
And now my controller snippet (expecting a file passed in the params[:file])...:
if params[:file]
@upload = Upload.new
@upload.newname = @upload.upload(params[:file])
@upload.oldname = @upload.get_original(params[:file])
@upload.directory = "/your/directory/here/"
@upload.user_id = session[:user]
@upload.save
flash[:notice] = "File Uploaded"
else
flash[:notice] = "File Not Uploaded"
end
That is it. You can use this Model to help you upload and save files to a folder on your site. Then store some important file tracking data to your database. Not first class material, but it works - and for a ruby / rails beginner that is a bit rough around the edges still - it will suffice. I plan on refining it further, and I would like to add more features - but that is for another day!

sgoodwin said:
Thanks much, your post was very informative and helped me out on my own project.
2006-08-02 14:32:59 UTCCharles said:
You are most welcome, glad it helped!
2006-08-03 17:30:37 UTCCharles said:
A note - Lightty behind my Apache server doesn't play nice with Dir.pwd or gwd Ruby methods.
(This only pertains to those people using Lighttpd proxied behind Apache2 - as my post on Aug-8-2006 discusses)
I had problems moving data from my /tmp directory to the working directory of my Rails app.
The reason? -- This setup caused my File.Mv and gwd commands do something like this:
/tmp/CGI00021.tmp -> //uploads/images/newfile.png
Notice the // -- it dropped the full directory path to the file (/home/www/www.forthecode.com/web/uploads/...)
My quick fix was hardcoding the full path in my model. Once I get some more time to debug this problem I'll write up a more complete solution.
2006-08-17 21:16:19 UTCCharles said:
Again, as with the simple FileUtils.mv command, this will only work with files larger than 10k (as mentioned throughout the rails wiki).
2006-08-28 23:17:47 UTCBud said:
Beware! This file upload code won't always work. If the file is small (I think < 10k) then a /tmp/CGI* file is not created. Instead the file is kept in storage as an IOStream object. When this happens the only file class method that always works is File.read. File.path returns null. The file must be moved from storage using File.read's and File.write's (or similar) to the permanent file name.
2007-04-17 23:15:11 UTCCharles said:
Thanks Bud for providing the solution. I never did get back to this after stating the same less than 10k problem (as noted in the comment above).
Life has kept me quite busy - plan on updating again soon.
2007-04-17 23:26:06 UTCBud said:
Actually, what made this so difficult to debug was that sometimes the smaller files were sent to /tmp! I think the decision to keep the data in core depended on the results of a malloc at the time of the upload.
2007-04-19 14:35:29 UTC