Uploading Files and Images with Rails File_Column (FileColumn plugin)

Posted on May 20th, 2007 in How To, Ruby on Rails by bjones

File_column is a plugin for the Ruby on Rails framework that enables easy uploading of files, especially images.

Suppose you have a list of users, and you would like to associate a picture to each of them. You could upload the image to a database, or you could use file_column for simple storage to the file system.

Let‘s create our database first, generate a migration (if you‘re not using migrations yet you are missing out!) and add

The FileColumn module allows you to easily handle file uploads. You can designate
one or more columns of your model’s table as “file columns”.

For this example, we’ll add only one, and call it “picture”.

Here is the migration/ table layout.

create_table "users" do |t|
t.column "name", :string
t.column "picture", :string
end

Now in your User class, just add the file_column method, and give it the name of your file_column (picture).

class User < ActiveRecord::Base

file_column :picture
end

Now just open up your existing user form, and edit it so it looks like the following:

<p><label for="user_picture">Picture</label><br/>
<%= file_column_field "user", "picture" %></p>

We‘ll need to set the form to multipart, so that the picture will actually be sent as well.
For my Create View
This makes a new user, and allows an image upload.
<%= form_tag( { :action => 'create' }, :multipart => true ) %>
<p><label for="user_name">Name</label><br/>
<%= text_field 'user', 'name' %></p>

<p><label for="user_picture">Picture</label><br/>
<%= file_column_field "user", "picture" %>

<%= submit_tag "Create" %>

</form>

For my Update View
This allows an existing user to add or update an image.
<%= start_form_tag({:action => 'update', :id => @user}, :multipart => true) %>
<p><label for="user_name">Description</label><br/>
<%= text_field 'user', 'name' %></p>

<p><label for="user_picture">Picture</label><br/>
<%= file_column_field "user", "picture" %>

<%= submit_tag 'Edit' %>
</form>

Validating File Size for file_column

class User < ActiveRecord::Base
file_column :picture
validates_filesize_of :picture, :in => 50.kilobytes..100.kilobytes
end

More examples:
validates_filesize_of :field, :in => 0..100.megabytes
validates_filesize_of :field, :in => 15.kilobytes..1.megabyte
validates_file_format_of :field, :in => ["gif", "png", "jpg"]
validates_file_format_of :field, :in => ["image/jpeg"]

More File_Column Documentation

modified from the File_Column source.
Now, by default, an uploaded file “test.png” for a user object with primary key 42 will
be stored in in “public/user/picture/42/test.png”. The filename “test.png” will be stored
in the record’s “picture” column. The “entries” table should have a +VARCHAR+ column
named “picture”.

After calling “file_column :picture” as in the example above, a number of instance methods
will automatically be generated, all prefixed by “picture”:

* User#picture=(uploaded_file): this will handle a newly uploaded file
(see below). Note that
you can simply call your upload field “user[picture]” in your view (or use the
helper).
* User#picture(subdir=nil): This will return an absolute path (as a
string) to the currently uploaded file
or nil if no file has been uploaded
* User#picture_relative_path(subdir=nil): This will return a path relative to
this file column’s base directory
as a string or nil if no file has been uploaded. This would be “42/test.png” in the example.
* User#picture_just_uploaded?: Returns true if a new file has been uploaded to this instance.
You can use this in your code to perform certain actions (e. g., validation,
custom post-processing) only on newly uploaded files.

You can access the raw value of the “picture” column (which will contain the filename) via the
ActiveRecord::Base#attributes or ActiveRecord::Base#[] methods like this:

user[’picture’] # e.g.”test.png”

Storage of uploaded files

For a model class +User+ and a column +picture+, all files will be stored under
“public/user/picture”. A sub-directory named after the primary key of the object will
be created, so that files can be stored using their real filename. For example, a file
“test.png” stored in a User object with id 42 will be stored in

public/user/picture/42/test.png

Files will be moved to this location in an +after_save+ callback. They will be stored in
a temporary location previously as explained in the next section.

By default, files will be created with unix permissions of 0644 (i. e., owner has
read/write access, group and others only have read access). You can customize
this by passing the desired mode as a :permissions options. The value
you give here is passed directly to File::chmod, so on Unix you should
give some octal value like 0644, for example.

Handling of form redisplay

Suppose you have a form for creating a new object where the user can upload an image. The form may
have to be re-displayed because of validation errors. The uploaded file has to be stored somewhere so
that the user does not have to upload it again. FileColumn will store these in a temporary directory
(called “tmp” and located under the column’s base directory by default) so that it can be moved to
the final location if the object is successfully created. If the form is never completed, though, you
can easily remove all the images in this “tmp” directory once per day or so.

So in the example above, the picture “test.png” would first be stored in
“public/user/picture/tmp//test.png” and be moved to
“public/user/picture/
/test.png”.

This temporary location of newly uploaded files has another advantage when updating objects. If the
update fails for some reasons (e.g. due to validations), the existing picture will not be overwritten, so
it has a kind of “transactional behaviour”.

Additional Files and Directories

FileColumn allows you to keep more than one file in a directory and will move/delete
all the files and directories it finds in a model object’s directory when necessary.

As a convenience you can access files stored in sub-directories via the +subdir+
parameter if they have the same filename.

Suppose your uploaded file is named “vancouver.jpg” and you want to create a
thumb-nail and store it in the “thumb” directory. If you call
picture(”thumb”), you
will receive an absolute path for the file “thumb/vancouver.jpg” in the same
directory “vancouver.jpg” is stored. Look at the documentation of FileColumn::Magick
for more examples and how to create these thumb-nails automatically.

File Extensions

FileColumn will try to fix the file extension of uploaded files, so that
the files are served with the correct mime-type by your web-server. Most
web-servers are setting the mime-type based on the file’s extension. You
can disable this behaviour by passing the :fix_file_extensions option
with a value of +nil+ to +file_column+.

In order to set the correct extension, FileColumn tries to determine
the files mime-type first. It then uses the +MIME_EXTENSIONS+ hash to
choose the corresponding file extension. You can override this hash
by passing in a :mime_extensions option to +file_column+.

The mime-type of the uploaded file is determined with the following steps:

1. Run the external “file” utility. You can specify the full path to
the executable in the :file_exec option or set this option
to +nil+ to disable this step

2. If the file utility couldn’t determine the mime-type or the utility was not
present, the content-type provided by the user’s browser is used
as a fallback.

Custom Storage Directories

FileColumn’s storage location is determined in the following way. All
files are saved below the so-called “root_path” directory, which defaults to
“RAILS_ROOT/public”. For every file_column, you can set a separte “store_dir”
option. It defaults to “model_name/attribute_name”.

Files will always be stored in sub-directories of the store_dir path. The
subdirectory is named after the instance’s +id+ attribute for a saved model,
or “tmp/” for unsaved models.

You can specify a custom root_path by setting the :root_path option.

You can specify a custom storage_dir by setting the :storage_dir option.

For setting a static storage_dir that doesn’t change with respect to a particular
instance, you assign :storage_dir a String representing a directory
as an absolute path.

If you need more fine-grained control over the storage directory, you
can use the name of a callback-method as a symbol for the
:store_dir option. This method has to be defined as an
instance method in your model. It will be called without any arguments
whenever the storage directory for an uploaded file is needed. It should return
a String representing a directory relativeo to root_path.

Uploaded files for unsaved models objects will be stored in a temporary
directory. By default this directory will be a “tmp” directory in
your :store_dir. You can override this via the
:tmp_base_dir option.

How to Un-tar gz files in Unix/Linux

Posted on May 19th, 2007 in How To, Unix by bjones

Open your shell
Here we’ll be uncompressing a file called archivedfile.tar.gz:

tar xvzf archivedfile.tar.gz

That’s it. :)

Ruby on Rails URL, Email, and IP Validation

Posted on May 19th, 2007 in How To, Ruby on Rails by bjones

Validating an Email Address

validates_format_of(:email,
                    :with => /^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i,
                    :on => :create,
                    :message=>"has an invalid format")

Validating URLs

validates_format_of :url, :with => /^(https?://)?([^/]+)(/.+)?$/i

# OR

validates_format_of :url, :with => /^(ftp|https?)://((?:[-a-z0-9]+.)+[a-z]{2,})/

Validating IP addresses

validates_format_of :ip, :with => /^(d{1,3}.d{1,3}.d{1,3}.d{1,3})?$/

Installing a Wordpress Blog

Posted on October 13th, 2006 in How To, blogs, Wordpress by bjones

Pages: 1 2 3

I’m about to install a new Wordpress blog, so I thought I’d fully document the process, so here goes.
(I’m assuming that you have a hosting plan and a domain name set up already.)

Pages: 1 2 3

Problem Solving: Getting Unstuck with Google

Posted on October 8th, 2006 in General, How To by bjones

Since I started programming, I have really relied pretty heavily on Google for solving programming and web developing problems. I usually just copy and paste whatever error I’m getting right into Google.

9 out of 10 times, I’ll find the solution to my problem pretty fast.

Earlier this week, I installed Fedora Core 5 on my old Blue and White Apple G3.

GoDaddy: Cheap Dedicated IP Hosting

Posted on October 8th, 2006 in How To, Hosting by bjones

I just set up a new “economy hosting” plan with Godaddy.com for a project that I’m working on. I have heard both good and bad things about Godaddy’s hosting, but this site doesn’t require much space or transfer, so I’m not really concerned about having a top notch host right now.

Here’s what I got, and how much it cost.

Bluetooth + Cellphone + Laptop = Wireless Internet for under $6/month

Posted on October 3rd, 2006 in Internet Service Providers, How To, Wireless Internet by bjones

Pages: 1 2 3 4

mobile phone as modem 01This tutorial will describe how to set up a GPRS GSM Phone as a Mobile Modem. More specifically, how to use a Nokia 6103 (with T-Mobile’s $5.99 T-Zones Internet service) as a GPRS modem that you can connect to using the Bluetooth connection of an Apple MacBook running Mac OS X Tiger (10.4.7). I set out to do this last week, and I never did find a specific tutorial for it, but by using about 5 different sources, I was able to get connected. If you have a different phone, or a different computer, this tutorial may still be useful.

Setting up the Phone:
For the phone, we’re going to need to set up a new APN or Access Point.

Pages: 1 2 3 4