When I first downloaded the Ruby on Rails plugin acts_as_attachment, I couldn’t understand why the only tutorials I could find did not show how to update the model and the attachment model in the same form. After all, why would you want to put your user through two actions when one would suffice?
I will expand on the DVD Cover example. Some of the code below is blatantly stolen from that tutorial.
Intall the plugin:
> script/plugin source http://svn.techno-weenie.net/projects/plugins
> script/plugin install acts_as_attachment
> rake test_plugins PLUGIN=acts_as_attachment
Generate the Models:
> script/generate model dvd
> script/generate attachment_model dvd_cover
Update your Database:
create_table :dvd
do |t|
t.
column "name", :
string
t.
column "studio", :
string
t.
column "producer", :
string
end
create_table :dvd_covers do |t|
t.column "dvd_id", :integer
t.column "content_type", :string
t.column "filename", :string
t.column "size", :integer
# The following fields are not mandatory.
t.column "parent_id", :integer
t.column "thumbnail", :string
t.column "width", :integer
t.column "height", :integer
end
Edit the Models:
class Dvd < ActiveRecord::Base
has_one :dvd_cover
end
class DvdCover < ActiveRecord::Base
belongs_to :dvd
acts_as_attachment :storage => :file_system
validates_as_attachment
end
The Controller:
class DvdController < ApplicationController
def index
@dvd = Dvd.find(:all)
end
def new_dvd
@dvd = params[:id].nil? ? Dvd.new : Dvd.find(params[:id])
@dvd_cover = DvdCover.new(params[:dvd_cover])
if request.post?
@dvd.attributes = params[:dvd]
@dvd_cover.attributes = params[:dvd_cover]
def save_dvd
Dvd.transaction do
@dvd.save!
@dvd_cover.dvd_id = @dvd.id
@dvd_cover.save!
end
end
redirect_to(:action => "index") and return if save_dvd
end
rescue ActiveRecord::RecordInvalid
end
end
The View:
(app/views/new_dvd.rhtml)
<%= error_messages_for :dvd %>
<%= error_messages_for :dvd_cover %>
<%= form_tag({:action => "new_dvd"}, { :multipart=>true }) %>
<label for="name"><strong>Name:</strong></label>
<%= text_field("dvd", "name", "size" => 50, "maxlength" => 50) %>
<label for="name"><strong>Studio:</strong></label>
<%= text_field("dvd", "studio", "size" => 50, "maxlength" => 50) %>
<label for="name"><strong>Producer:</strong></label>
<%= text_field("dvd", "producer", "size" => 50, "maxlength" => 50) %>
<label for="name"><strong>DVD Cover:</strong></label>
<%= file_field("dvd_cover", "uploaded_data") %>
<%= submit_tag ‘Create DVD’ %>
<%= end_form_tag %>
This will give you 1 form to create the DVD and upload the DVD Cover.