# File upload

**URL:** <https://www.ruby-forum.com/t/file-upload/93979>\
**Category:** Rails\
**Created:** [April 17, 2006, 4:27pm UTC](https://www.ruby-forum.com/t/file-upload/93979 "2006-04-17T16:27:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [April 17, 2006, 4:27pm UTC](https://www.ruby-forum.com/t/file-upload/93979/1 "2006-04-17T16:27:51Z")

</div>

This is probably me having an issue with the mvc way of living… .I’m  
used to perl/php scripting…

I’ve got a photo blog I’m making… and in past iterations of this  
website, I’d just name the photos after the id of the entry. For  
instance:

/photos/id.jpg  
/photos/id\_thumb.jpg

However, I’m having trouble finding an easy way to do this with rails.

Everywhere I read either has an example of how to upload the file  
directly into a database, or to use file\_column. While file\_column  
looks nice and easy, it kind of bugs me that I’d have to create two  
columns in my table to support the ability to upload a file… if I  
have to do this, then I will, but I was curious if there is any easy way  
to do this.

The only possibility I found was here:  
[http://wiki.rubyonrails.com/rails/pages/HowtoUploadFiles](http://wiki.rubyonrails.com/rails/pages/HowtoUploadFiles)

However, there were a couple of things I wasn’t sure on:

1. in the view:  

What is [picture] a reference to? this isn’t being stored in the  
database… is it just so we can access it with the person class?

1. The use of file.open… I haven’t had much luck finding  
documentation on all the options…

File.open(“pictures/#{person[‘name’]}/picture.jpg”, “w”) { |f|  
f.write(person[‘picture’].read) }

I’d really appreciate any help or suggestions.  
Thanks  
-tyler

---

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [April 17, 2006, 7:15pm UTC](https://www.ruby-forum.com/t/file-upload/93979/2 "2006-04-17T19:15:52Z")

</div>

Hi tyler,

I got my fileupload running yesterday for our tumblelog:  
[http://pkk.kuebelreiter.net/](http://pkk.kuebelreiter.net/)

We wanted to upload files simply to /public/images, without any  
database or sth like that.  
And I didn’t want to associate my images to my Items.

So this is how i managed it:

Created an model image:  
class Image  
end

(it is emtpy yet, but I wanted to include a method for the override  
problem, if a file already exists. But there were some troubles with  
that…).

Then I generated a controller image in my admin-directory:

class Admin::ImageController \< ApplicationController

def create  
File.open(RAILS\_ROOT +  
“/public/images/#{@params[‘picture’].original\_filename}”, “w”) { |f|  
f.write(@params[“picture”].read) }  
redirect\_to :controller =\> ‘tumble’, :action =\> “new”, :bildpfad  
=\> @request.protocol + @request.host\_with\_port +  
“/images/#{@params[‘picture’].original\_filename}”  
end

def new  
@image = Image.new  
end

end

And a template under admin/image/new.rthtml:

\<%= form\_tag({ :action =\> “create” }, :multipart =\> true) %\>

Image:

\<%= submit\_tag 'upload' %\>

\<%= end\_form\_tag %\>

Thats all 😉  
If you want to rename your files with your post.id, you have to  
include the file-logic in your post-controller, to have the post.id.  
But I think you get the idea.

You might also look into typo, there is a file-upload for each artikle.

HTH,  
Beate

---

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [April 17, 2006, 7:19pm UTC](https://www.ruby-forum.com/t/file-upload/93979/3 "2006-04-17T19:19:04Z")

</div>

tyler craft wrote:

> This is probably me having an issue with the mvc way of living… .I’m  
> used to perl/php scripting…

mvc is a design pattern - can be implemented in any language [well  
within reason]

> looks nice and easy, it kind of bugs me that I’d have to create two  
> columns in my table to support the ability to upload a file… if I  
> have to do this, then I will, but I was curious if there is any easy way  
> to do this.

Do you want to store the image on the disk or in a database?

> The only possibility I found was here:  
> [Peak Obsession](http://wiki.rubyonrails.com/rails/pages/HowtoUploadFiles)
> 
> However, there were a couple of things I wasn’t sure on:
> 
> 1. in the view:  
> 
> What is [picture] a reference to? this isn’t being stored in the  
> database… is it just so we can access it with the person class?

Yes this assumes that there is an object called person [likely an  
instnance of ActiveRecord] that has an attribute called picture [which  
would most likely be a BLOB in a database somewhere] - to remove the  
OOP, you could do this:

Then access in your controller with: @params[‘picture’]

> 1. The use of file.open… I haven’t had much luck finding  
> documentation on all the options…

[http://corelib.rubyonrails.org/classes/File.html](http://corelib.rubyonrails.org/classes/File.html)

> File.open(“pictures/#{person[‘name’]}/picture.jpg”, “w”) { |f|  
> f.write(person[‘picture’].read) }

the File.new and File.open methods are essentially the same thing  
[expect open allows for an included block, i.e the {|f|… bit] - whats  
confusing is that you have to ‘open’ a file to create it [it actually  
makes sense if you got a deep understanding of how file systems work,  
but…] - f.write is an input stream for the file, picture.read is an  
output stream for the incoming file, i.e. it is read to a write buffer…  
this is for writing to a disk btw and not for a database… clarify  
which one youre attempting to do.

---

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [April 17, 2006, 8:32pm UTC](https://www.ruby-forum.com/t/file-upload/93979/4 "2006-04-17T20:32:18Z")

</div>

Thanks for the responses.

To clarify, I am simply wanting to save the file to disk, not in a  
database.

So, for an example, in my admin/photo view, I’d have this:

Then, in my admin/photo controller would I then call a function in the  
photo model and have this code:

File.open(“photos/#{valuePassedIn}.jpg”, “w”) { |f|  
f.write(@params[‘picture’].read) }

Thanks again!  
-tyler

---

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [April 17, 2006, 9:09pm UTC](https://www.ruby-forum.com/t/file-upload/93979/5 "2006-04-17T21:09:42Z")

</div>

FileColumn only uses one field, a :string in migrations parlance, i.e.  
varchar in typical SQL. In the db it stores the filename of the uploaded  
file. If you have that field and

file\_column :field\_name

in the model, you’re off and running.

tyler craft wrote:

> This is probably me having an issue with the mvc way of living… .I’m  
> used to perl/php scripting…
> 
> I’ve got a photo blog I’m making… and in past iterations of this  
> website, I’d just name the photos after the id of the entry. For  
> instance:
> 
> /photos/id.jpg  
> /photos/id\_thumb.jpg
> 
> However, I’m having trouble finding an easy way to do this with rails.
> 
> Everywhere I read either has an example of how to upload the file  
> directly into a database, or to use file\_column. While file\_column  
> looks nice and easy, it kind of bugs me that I’d have to create two  
> columns in my table to support the ability to upload a file… if I  
> have to do this, then I will, but I was curious if there is any easy way  
> to do this.

---

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [April 17, 2006, 10:04pm UTC](https://www.ruby-forum.com/t/file-upload/93979/6 "2006-04-17T22:04:04Z")

</div>

Steve K. wrote:

> FileColumn only uses one field, a :string in migrations parlance, i.e.  
> varchar in typical SQL. In the db it stores the filename of the uploaded  
> file. If you have that field and
> 
> file\_column :field\_name
> 
> in the model, you’re off and running.

But what if I want multiple photos? For instance, a small/medium/large?  
Would I need three extra columns?

…I should be able to have it just name the file off the id and just  
through the images into a small/medium/large folder.

---

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [April 17, 2006, 10:48pm UTC](https://www.ruby-forum.com/t/file-upload/93979/7 "2006-04-17T22:48:34Z")

</div>

If you want multiple versions of the same image, all you do is install  
the RMagick gem or ImageMagick on your machine(s) and in your model you  
can then say something like

file\_column :field\_name, :magick =\> {:versions =\>  
{ “thumb” =\> “80x60”, “small” =\> “150x120”, “medium” =\> “250x200”,  
“large” =\> “640x480” }}

and poof! You have multiple versions of the image all generated, named  
and saved automatically. Yes, there’s also syntax for constraining one  
axis and scaling the other proportaionally. And to display the thumbnail  
of, for instance, @photo.image, you’d then simply say

\<%= image\_tag url\_for\_file\_column “photo”, “image”, “thumb” =%\>

As for multiple distinct images in the same table row, you simply have a  
file\_column declaration for each one in the model:

Class House \< ActiveRecord::Base  
file\_column :front\_view, :magick =\> {:versions =\> { “thumb” =\>  
“80x60” }  
file\_column :floorplan  
file\_column :kitchen\_photo  
end

And of course each of those can have all the resized or manipulated  
versions you want.

The file\_column docs could use somefleshing out, especially the README.  
😉

tyler craft wrote:

> Steve K. wrote:
> 
> > FileColumn only uses one field, a :string in migrations parlance, i.e.  
> > varchar in typical SQL. In the db it stores the filename of the uploaded  
> > file. If you have that field and
> > 
> > file\_column :field\_name
> > 
> > in the model, you’re off and running.
> 
> But what if I want multiple photos? For instance, a small/medium/large?  
> Would I need three extra columns?
> 
> …I should be able to have it just name the file off the id and just  
> through the images into a small/medium/large folder.

---

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [May 2, 2006, 2:43pm UTC](https://www.ruby-forum.com/t/file-upload/93979/8 "2006-05-02T14:43:25Z")

</div>

Beate P. wrote:

> Hi tyler,
> 
> I got my fileupload running yesterday for our tumblelog:  
> [http://pkk.kuebelreiter.net/](http://pkk.kuebelreiter.net/)
> 
> We wanted to upload files simply to /public/images, without any  
> database or sth like that.  
> And I didn’t want to associate my images to my Items.
> 
> So this is how i managed it:
> 
> Created an model image:  
> class Image  
> end
> 
> (it is emtpy yet, but I wanted to include a method for the override  
> problem, if a file already exists. But there were some troubles with  
> that…).
> 
> Then I generated a controller image in my admin-directory:
> 
> class Admin::ImageController \< ApplicationController
> 
> def create  
> File.open(RAILS\_ROOT +  
> “/public/images/#{@params[‘picture’].original\_filename}”, “w”) { |f|  
> f.write(@params[“picture”].read) }  
> redirect\_to :controller =\> ‘tumble’, :action =\> “new”, :bildpfad  
> =\> @request.protocol + @request.host\_with\_port +  
> “/images/#{@params[‘picture’].original\_filename}”  
> end
> 
> def new  
> @image = Image.new  
> end
> 
> end
> 
> And a template under admin/image/new.rthtml:
> 
> \<%= form\_tag({ :action =\> “create” }, :multipart =\> true) %\>
> 
> Image:
> 
> \<%= submit\_tag 'upload' %\>
> 
> \<%= end\_form\_tag %\>
> 
> Thats all 😉  
> If you want to rename your files with your post.id, you have to  
> include the file-logic in your post-controller, to have the post.id.  
> But I think you get the idea.
> 
> You might also look into typo, there is a file-upload for each artikle.
> 
> HTH,  
> Beate

I used this code, after runs this programme the images are uploaded into  
the images folder, but If iam trying to open uploaded images, those are  
opened but overlapped (I mean to say that not as the original image)  
with some other images. So plz help me out in uploading as the original  
image.

```
    and another thing is, I used this file tag in a form, after 

```

submit in the controller, it displayes an error as original\_filename  
undefined method.  
what I have to do.

Thanks in advance  
Surekha.Matte

---

<div class="post-metadata">

**Author:** ![tylerc083](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/9de053/32.png) [@tylerc083](https://www.ruby-forum.com/u/tylerc083)\
**Post date:** [May 2, 2006, 2:56pm UTC](https://www.ruby-forum.com/t/file-upload/93979/9 "2006-05-02T14:56:56Z")

</div>

this is the code I ended up using. I have a form that has an image  
submit button on it, and when i update it, I run this code:

if @photo.update\_attributes(params[:photo])  
if @params[“thumbnail”].size != 0  
File.open("#{RAILS\_ROOT}/public/photos/#{@photo.id}\_thumb.jpg",  
“wb”) { |f| f.write(@params[“thumbnail”].read) }  
end  
end
