目标:一个Rails模型(表格),其中包含多个继承自它的模型,每个模型都定义了自己的回形针has_attached_file
配置。
我曾经有一个上传课程,我正在使用paperclip。问题是,当我添加更多文件类型(pdf,word文档等)时,它们仍然通过“style”和“convert_options”处理为图像。此外,现在我需要在S3上存储一些文件,在本地存储其他文件。
那就是说,我一直在重组这样的东西,我现在有一个S3File,Contract和其他模型都继承自上传,它仍然继承自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
现在在我尝试查询数据的控制台中,它返回上传对象而不是S3File或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">
将响应作为上传类型是有问题的,因为它没有回形针附件。这些是在子类上定义的,每个子类都有has_attached_file
的唯一URL,路径和存储定义。
我看到了multiple models and paperclip和polymorphic multiple models paperclip个问题,但在这些问题中,每个“多个模型”都继承自ActiveRecord :: Base,我的目标是避免这种情况,因为我可以,因为数据结构是相同。
我对此的疑问是:
has_attached_file
(:item或:s3file)名称是个好主意还是让它们保持不变是有益的?答案 0 :(得分:2)
带有回形针的STI已经在几个问题#293,#601,#605中进行了讨论,现在是回形针的支持功能。
STI是正确的方法吗?
在我的情况下,这是正确的方法,因为我不想为每个模型使用多个表。为了解决查询project.contracts
和获取Upload
类型类时出现错误类的问题,这是一个记录在案的Rails功能。只需将class_name: "Contract
添加到模型的has_many即可解决此问题:
根据associations documentation on customizing the query:
自定义查询
关联是从Relations建立的,您可以使用Relation 语法来自定义它们。例如,要添加条件:
class Blog < ActiveRecord::Base
has_many :published_posts, -> { where published: true }, class_name: 'Post'
end
是否需要多态关联
在STI的情况下,没有。如果每个模型都支持db,那么多态关联可能有所帮助。有关示例,请参阅polymorphic associations with multiple models上的答案。
使用相同的has_attached_file
自上述拉动请求合并以来,这在回形针中不是问题。可以覆盖子类中的选项,回调,样式,url或路径,并享受OOP的优势以满足应用程序的需求。