# Attachment\_fu: Having problems with database\_backend

**URL:** <https://www.ruby-forum.com/t/attachment-fu-having-problems-with-database-backend/108234>\
**Category:** Rails\
**Created:** [June 30, 2007, 7:37pm UTC](https://www.ruby-forum.com/t/attachment-fu-having-problems-with-database-backend/108234 "2007-06-30T19:37:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [June 30, 2007, 7:37pm UTC](https://www.ruby-forum.com/t/attachment-fu-having-problems-with-database-backend/108234/1 "2007-06-30T19:37:50Z")

</div>

First, Rick O. - excellent plugin!  
Second, Mike C. - excellent tutorial on file\_system backend!  
Third, Ron Evans, excellent tutorial on database backend (http://  
[deadprogrammersociety.blogspot.com/2007/04/getting-your-attachmentfu-](http://deadprogrammersociety.blogspot.com/2007/04/getting-your-attachmentfu-)  
back-out-of.html)!

I am having serious trouble getting database storage working. I  
haven’t found much information regarding using attachment\_fu with a  
database backend, but I’ve almost got it working and have a strange  
bug.

It appears to be storing the entire file in the database, but when I  
pull it out and display it the image stops rendering after around 40K  
(haven’t measured exactly where it cuts off, but files smaller than  
about 40k render and download completely). It is the same when I  
download the file, the downloaded file has the right dimensions, but  
the image only fills up part of the size of the original. The part  
filled in is sequential from the beginning. I am very confused.

The other alternative for me is to store the files on the file system,  
but they must be protected from direct download. These are  
confidential documents that I am uploading (driver’s lisenses, birth  
certificates, social security cards, etc). Is there a way to protect  
the files from direct download and also allow them to be viewed and  
downloaded by logged in users (admins)?

## Thanks, Peter

(\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

- l\*eter H. l3oling
- Software Developer - Sagebit, LLC
- email: removed\_email\_address@domain.invalid
- blog: [http://galtzo.blogspot.com/](http://galtzo.blogspot.com/)
- languages: English, Spanish, Portuguese  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*)

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [July 1, 2007, 5:22pm UTC](https://www.ruby-forum.com/t/attachment-fu-having-problems-with-database-backend/108234/2 "2007-07-01T17:22:32Z")

</div>

My suggestion wrt safely storing as files:

1. store the files in a part of the file system not in the web server’s  
document root.
2. To send a file to a browser client, use a controller action to read  
and return the contents of the file. That way the controller action can  
check access, log the request, etc.

HTH,

Larry

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [July 1, 2007, 7:35pm UTC](https://www.ruby-forum.com/t/attachment-fu-having-problems-with-database-backend/108234/3 "2007-07-01T19:35:55Z")

</div>

On 7/1/07, Larry K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> HTH,  
> Are you sure your database isn’t truncating the files?

Using the filesystem is usually better though. It’s definitely faster  
and easier on memory (mongrel steams to a tmp file that you can just  
move, rather than opening it into memory).

For serving it, check out the x-accel-redirect header for nginx:  
[http://wiki.codemongers.com/NginxXSendfile](http://wiki.codemongers.com/NginxXSendfile)

–  
Rick O.  
[http://lighthouseapp.com](http://lighthouseapp.com)  
[http://weblog.techno-weenie.net](http://weblog.techno-weenie.net)  
[http://mephistoblog.com](http://mephistoblog.com)

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [July 1, 2007, 9:06pm UTC](https://www.ruby-forum.com/t/attachment-fu-having-problems-with-database-backend/108234/4 "2007-07-01T21:06:06Z")

</div>

On Jul 1, 2007, at 5:22 PM, Larry K. wrote:

> My suggestion wrt safely storing as files:
> 
> 1. store the files in a part of the file system not in the web  
> server’s  
> document root.
> 2. To send a file to a browser client, use a controller action to read  
> and return the contents of the file. That way the controller action  
> can  
> check access, log the request, etc.

In addition, you can avoid the penalty in your precious Rails  
processes delegating to the front-end server via the X-Sendfile  
header, there’s a plugin that encapsulates that:

[http://agilewebdevelopment.com/plugins/xsendfile](http://agilewebdevelopment.com/plugins/xsendfile)

Using that trick the flow becomes (think a regular Apache + Mongrel  
Cluster setup for example):

1. Files are requested with URLs that point to some  
controller instead of the public document root,  
thus the controller has complete control about their  
access according to the logic of the application

2. The action resolves the filename to fetch somehow,  
be careful with filenames, sanitize parameters, etc.

3. It calls some of the plugin’s send\_file()-like methods,  
which just add a header with the actual filename on  
disk for the front-end server to handle

4. The front-end server intercepts the response after  
seeing the special header, and serves the file in its  
value as if it was a regular public static file, it  
takes care of the MIME type etc.

In development mode you don’t need to use that necessarily, I use  
xsendfile’s drop in replacement for send\_file() only in production  
mode, it’s as easy as throwing this line into environment.rb:

XSendFile::Plugin.replace\_send\_file! if RAILS\_ENV == ‘production’

So that in development mode those files as always (for example by  
webrick), and in production the X-Sendfile stuff is activated without  
touching a single line of code.

– fxn

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [July 1, 2007, 9:10pm UTC](https://www.ruby-forum.com/t/attachment-fu-having-problems-with-database-backend/108234/5 "2007-07-01T21:10:06Z")

</div>

On Jul 1, 2007, at 5:22 PM, Larry K. wrote:

> My suggestion wrt safely storing as files:
> 
> 1. store the files in a part of the file system not in the web  
> server’s  
> document root.
> 2. To send a file to a browser client, use a controller action to read  
> and return the contents of the file. That way the controller action  
> can  
> check access, log the request, etc.

In addition, you can avoid the penalty in your precious Rails  
processes delegating to the front-end server via the X-Sendfile  
header, there’s a plugin that encapsulates that:

[http://agilewebdevelopment.com/plugins/xsendfile](http://agilewebdevelopment.com/plugins/xsendfile)

Using that trick the flow becomes (think a regular Apache + Mongrel  
Cluster setup for example):

1. Files are requested with URLs that point to some  
controller instead of the public document root,  
thus the controller has complete control about their  
access according to the logic of the application

2. The action resolves the filename to fetch somehow,  
be careful with filenames, sanitize parameters, etc.

3. It calls some of the plugin’s send\_file()-like methods,  
which just add a header with the actual filename on  
disk for the front-end server to handle

4. The front-end server intercepts the response after  
seeing the special header, and serves the file in its  
value as if it was a regular public static file, it  
takes care of the MIME type etc.

In development mode you don’t need to use that necessarily, I use  
xsendfile’s drop in replacement for send\_file() only in production  
mode, it’s as easy as throwing this line into environment.rb:

XSendFile::Plugin.replace\_send\_file! if RAILS\_ENV == ‘production’

So that in development mode those files as always (for example by  
webrick), and in production the X-Sendfile stuff is activated without  
touching a single line of code.

– fxn
