<p>I'm going to be starting a project soon that requires support for large-ish binary files. I'd like to use Ruby on Rails for the webapp, but I'm concerned with the BLOB support. In my experience with other languages, frameworks, and databases, BLOBs are often overlooked and thus have poor, difficult, and/or buggy functionality.</p>

<p>Does RoR spport BLOBs adequately? Are there any gotchas that creep up once you're already committed to Rails?</p>

<p>BTW: I want to be using PostgreSQL and/or MySQL as the backend database. Obviously, BLOB support in the underlying database is important. For the moment, I want to avoid focusing on the DB's BLOB capabilities; I'm more interested in how Rails itself reacts. Ideally, Rails should be hiding the details of the database from me, and so I should be able to switch from one to the other. If this is <em>not</em> the case (ie: there's some problem with using Rails with a particular DB) then please do mention it. </p>

<p>UPDATE: Also, I'm not just talking about ActiveRecord here. I'll need to handle binary files on the HTTP side (file upload effectively). That means getting access to the appropriate HTTP headers and streams via Rails. I've updated the question title and description to reflect this.</p>

[{'answer_id': 57112, 'author': 'Teflon Ted', 'author_id': 4061, 'author_profile': 'https://Stackoverflow.com/users/4061', 'pm_score': 2, 'selected': False, 'text': '<p>I think your best bet is the attachment_fu plug-in:\n<a href="http://github.com/technoweenie/attachment_fu/tree/master" rel="nofollow noreferrer">http://github.com/technoweenie/attachment_fu/tree/master</a></p>\n\n<p>UPDATE: Found some more info here <a href="http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/a81beffb93708bb3" rel="nofollow noreferrer">http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/a81beffb93708bb3</a></p>\n'}, {'answer_id': 57201, 'author': 'John Topley', 'author_id': 1450, 'author_profile': 'https://Stackoverflow.com/users/1450', 'pm_score': 3, 'selected': False, 'text': '<p>You can use the <code>:binary</code> type in your ActiveRecord migration and also constrain the maximum size:</p>\n\n<pre><code>class BlobTest &lt; ActiveRecord::Migration\n  def self.up\n    create_table :files do |t|\n      t.column :file_data, :binary, :limit =&gt; 1.megabyte\n    end\n  end\nend\n</code></pre>\n\n<p>ActiveRecord exposes the BLOB (or CLOB) contents as a Ruby String.</p>\n'}, {'answer_id': 57608, 'author': 'Matt Rogish', 'author_id': 2590, 'author_profile': 'https://Stackoverflow.com/users/2590', 'pm_score': 4, 'selected': True, 'text': "<p>+1 for attachment_fu</p>\n\n<p>I use attachment_fu in one of my apps and MUST store files in the DB (for annoying reasons which are outside the scope of this convo).</p>\n\n<p>The (one?) tricky thing dealing w/BLOB's I've found is that you need a separate code path to send the data to the user -- you can't simply in-line a path on the filesystem like you would if it was a plain-Jane file.</p>\n\n<p>e.g. if you're storing avatar information, you can't simply do:</p>\n\n<pre><code>&lt;%= image_tag @youruser.avatar.path %&gt;\n</code></pre>\n\n<p>you have to write some wrapper logic and use send_data, e.g. (below is JUST an example w/attachment_fu, in practice you'd need to DRY this up)</p>\n\n<pre><code>send_data(@youruser.avatar.current_data, :type =&gt; @youruser.avatar.content_type, :filename =&gt; @youruser.avatar.filename, :disposition =&gt; 'inline' )\n</code></pre>\n\n<p>Unfortunately, as far as I know attachment_fu (I don't have the latest version) does not do clever wrapping for you -- you've gotta write it yourself.</p>\n\n<p>P.S.\nSeeing your question edit - Attachment_fu handles all that annoying stuff that you mention -- about needing to know file paths and all that crap -- EXCEPT the one little issue when storing in the DB. Give it a try; it's the standard for rails apps. IF you insist on re-inventing the wheel, the source code for attachment_fu should document most of the gotchas, too!</p>\n"}, {'answer_id': 58208, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>Look into the plugin, <a href="http://john.guen.in/rdoc/x_send_file/" rel="nofollow noreferrer">x_send_file</a> too. </p>\n\n<p>"The XSendFile plugin provides a simple interface for sending files via the X-Sendfile HTTP header. This enables your web server to serve the file directly from disk, instead of streaming it through your Rails process. This is faster and saves a lot of memory if you‘re using Mongrel. Not every web server supports this header. YMMV."</p>\n\n<p>I\'m not sure if it\'s usable with Blobs, it may just be for files on the file system. But you probably need something that doesn\'t tie up the web server streaming large chunks of data.</p>\n'}, {'answer_id': 58377, 'author': 'Jim Puls', 'author_id': 6010, 'author_profile': 'https://Stackoverflow.com/users/6010', 'pm_score': 4, 'selected': False, 'text': "<p>As for streaming, you can do it all in an (at least memory-) efficient way. On the upload side, file parameters in forms are abstracted as IO objects that you can read from; on the download side, look in to the form of <code>render :text =&gt;</code> that takes a Proc argument:</p>\n\n<pre><code>render :content_type =&gt; 'application/octet-stream', :text =&gt; Proc.new {\n    |response, output|\n    # do something that reads data and writes it to output\n}\n</code></pre>\n\n<p>If your stuff is in files on disk, though, the aforementioned solutions will certainly work better.</p>\n"}]
['https://Stackoverflow.com/questions/57104', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3488/']