Goal: One Rails model (table) with multiple models which inherit from it, each which define their own paperclip has_attached_file
configurations.
I used to have a single Upload class which I was using with paperclip. The problem is that as I added more file types (pdfs, word documents etc.) they were still being processed as images via the "style" and "convert_options". Further, now I need to have some files stored on S3 and others stored locally.
That said, I've been restructuring things such that I now have an S3File, Contract and other models all which inherit from Upload which still inherits from ActiveRecord::Base.
# app/models/project.rb
class Project < ActiveRecord::Base
has_many :contracts, :dependent => :destroy
accepts_nested_attributes_for :contracts, :allow_destroy => true
has_many :s3_files, :dependent => :destroy
accepts_nested_attributes_for :s3_files, :allow_destroy => true
# ...
end
# app/models/upload.rb
class Upload < ActiveRecord::Base
belongs_to :project
end
# app/models/contract.rb
class Contract < Upload
has_attached_file :item,
:url => "/projects/:project_id/uploads/:id/:basename.:extension",
:path => ":rails_root/public/:class/:attachment/:id/:basename.:extension"
do_not_validate_attachment_file_type :item
end
# app/models/s3_file.rb
class S3File < Upload
has_attached_file :s3file,
storage: :s3,
url: ':s3_domain_url',
path: lambda {|u| 'files/:basename.:extension' }
do_not_validate_attachment_file_type :s3file
end
Now in a console when I try and query the data, it returns Upload objects and not the S3File or Contract.
irb(main):005:0> Project.first.contracts
=> #<Upload id: 14833, project_id: 9717, upload_type: "private", item_file_name: "abcd.pdf", item_category: "contracts", item_content_type: "application/pdf", item_file_size: 671367, rake_processed: 0, name: "", created_at: "2013-05-30 20:05:02", updated_at: "2013-05-30 20:05:02">
Having the response as an Upload type is problematic because it has no paperclip attachment. These are defined on the subclasses which each have a unique url, path and storage definitions for the has_attached_file
.
I saw the multiple models and paperclip and polymorphic multiple models paperclip questions but in those questions each of the "multiple models" inherit from ActiveRecord::Base, my goal is to avoid that if I can since the data structures are the same.
My questions about this are:
- Is this the right approach for having files types with various storage backends with one table? Being files, they mostly all have the same attributes, so having multiple tables for each of these models seems unnecessary.
- Do I need to be using polymorphic associations? How would I define those here? I couldn't get it to work, plus it doesn't seem appropriate since the Contract and S3File are Upload type anyway, they do not have their own table.
- Is it a good idea to use separate
has_attached_file
(:item or :s3file) names or is it beneficial to have them remain the same?