To answer your last question, you have two options:
Code:
if item.deliverable.download != 0
Or:
Code:
unless item.deliverable.download == 0
Whichever reads better to you.
For your main question, I would extract most of the logic to the model and I wouldn't bother storing the uploaded files in separate folders according to type because it makes things simpler and it makes little difference - the file can be stored anywhere and named anything (no file extension needed either) as long as you have a record of the content type in your database - this can be saved when its originally uploaded.
In the following example, attachments are stored in /var/www/attachments and they are saved using the format attachment_ID
The model:
Code:
class Deliverable < ActiveRecord::Base
def self.save_path(path)
@@save_path = path
end
def attachment_path
"#{@@save_path}/attachment_#{self.id}"
end
end
Set your attachment path, in application.rb:
Code:
Deliverable.save_path = '/var/www/attachments'
Now your controller code is as simple as:
Code:
def download
begin
@order = Order.find(params[:id], :conditions => "ordered_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)")
rescue
redirect_to_index("Sorry, that's an invalid order.")
end
begin
@file = @order.line_items.find(:first, :conditions => ["deliverable_id = ?", params[:file]])
rescue
redirect_to_index("Sorry, you did not order that file.")
return
end
send_file @file.deliverable.attachment_path, :type => @file.deliverable.content_type
end
One gotcha, even though the right content type will be sent for the download, it will simply be named attachment_ID without a file extension. Don't forget you can send a custom name for the file with send_file() so you may want to do that to give the download a more descriptive name (perhaps using some existing metadata you have about the file in the database, or perhaps the original filename if you store that in the db when its originally uploaded).
Bookmarks