Does acts_as_attachment :storage => :db_system work?

I found the post about needing to install acts_as_attachement_1_1_6 if you are not on edge rails. But I am having trouble getting db_system storage to work. As far as I can tell in from the database, things are working, but I don't see how my model table hooks up with the db_files table so I am having trouble altering the image_tag from the tutorial ( so that it pulls data from the database. (Everything works fine if I want to use :storage => :file_system)

How are my generated model and db_files connected? and what do I need in my show action to send the image to the browser? I tried code like this:

    send_data, :filename => @picture.filename, :type => @picture.content_type, :dispo\ sition => 'inline'

But I get an undefined method error for data_file, which doesn't surprise me since I don't see any link between the db_files table and my pictures table. Parent_id could have been it, but a) it is blank and b) the docs seem to indicate that is used mainly for keeping track of which images are just resized versions of other images.


    send_data, :filename => @picture.filename, :type => @picture.content_type, :dispo\ sition => 'inline'

Shouldn't that be db_file, not data_file?

> send_data, :filename => @picture.filename, > :type => @picture.content_type, :dispo sition => 'inline'

Shouldn't that be db_file, not data_file?

OOps. yes. But that just gets me to a different error message:

  You have a nil object when you didn't expect it!   The error occured while evaluating

And while trying to double check that I had not messed anything up, I am reminded that to get as far as I did, I had had to comment out another piece of code that was causing errors. So for a full recap:

I have Rails 1.1.6 installed on a RHEL 4 system running ruby 1.8.4 (installed from source). I installed acts_as_attachment using the command "script/plugin install" If I set the DB environment variable, running the test "rake test_plugins PLUGIN=acts_as_attachment" seems to work - but I had expected more output - such as a list of # of tests and # passed.

If I set my Picture model up to use :storage => :file_system, all seems to work just fine. To try to use :db_system, I needed to uncomment the lines about db_file before running the migration built when I did "script/generate attachment_model picture". Then I set up my model up like:

class Picture < ActiveRecord::Base   acts_as_attachment :storage => :db_system, :max_size => 500.kilobytes, :content_type => :image   validates_as_attachment end

and my controller like this:

class PictureController < ApplicationController   def index     @pictures = Picture.find(:all)   end

  def new     @picture =   end

  def show     @picture = Picture.find(params[:id])     send_data, :filename => @picture.filename, :type => @picture.content_type, :disposition => 'inline'   end

  def create     @picture = Picture.create params[:picture]     redirect_to :action => 'show', :id => @picture   rescue ActiveRecord::RecordInvalid     render :action => 'new'   end end

When I try to upload a new image, I can see the following exception:

undefined method `db_file_id=' for #<Picture:0xb77f83fc>

RAILS_ROOT: /rails/admissions/script/../config/.. Application Trace | Framework Trace | Full Trace

/software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/base.rb:1789:in `method_missing' #{RAILS_ROOT}/vendor/plugins/acts_as_attachment-1.1.6/lib/technoweenie/acts_as_attachment.rb:316:in `save_to_storage' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/callbacks.rb:333:in `callback' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/callbacks.rb:330:in `callback' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/callbacks.rb:248:in `create_or_update' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/base.rb:1392:in `save_without_validation' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/validations.rb:724:in `save_without_transactions' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/transactions.rb:126:in `save' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/connection_adapters/abstract/database_statements.rb:51:in `transaction' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/transactions.rb:91:in `transaction' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/transactions.rb:118:in `transaction' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/transactions.rb:126:in `save' /software/stow/ruby-1.8.4/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/base.rb:408:in `create' #{RAILS_ROOT}/app/controllers/picture_controller.rb:16:in `create'

In the module DbFileMethods section of acts_as_attachment.rb, I commented out the line that calls db_file_id= and then I can upload files. I see the insert statements for both db_files and pictures and looking in the database, I see roughly the data I expect (Can't easily inspect the image from the terminal, but it is of the same length as the length stored in pictures.size. But when I try to use the show method above, I get the error at the top of this post. And I am having trouble working backwards from the only code that seems it ties pictures to db_files to the syntax I need in my show controller so I can display the images right out of the database. Is this the code that tells the the two tables they are related?

    module DbFileMethods def self.included(base) #:nodoc:         base.belongs_to :db_file         base.before_save :save_to_storage # so the db_file_id can be set       end

And I would have expected one or the other table to have a foreign key. What am I missing?

undefined method `db_file_id=' for #<Picture:0xb77f83fc>

That means you're missing the db_file_id row. This points your attachment to the row in the db_files table. Removing the part that sets this in the plugin means the two are never attached.

Thanks Rick. I added the column to my created table and now everything works. Can I ask that you patch acts_as_attachment-1.1.6/generators/attachment_model/templates/migration.rb to have the following lines somewhere within the create table definition:

      # uncomment this before migrating if you want db-based files       # t.column "db_file_id", :integer

Thanks. Great product, now that you showed me the trick to making db_system work.