【问题标题】:Multiple models with paperclip using STI使用 STI 的带有回形针的多个模型
【发布时间】:2016-03-15 21:34:58
【问题描述】:

目标:一个 Rails 模型(表格),其中包含多个继承自它的模型,每个模型定义自己的回形针 has_attached_file 配置。

我曾经有一个与回形针一起使用的上传类。问题在于,当我添加更多文件类型(pdf、word 文档等)时,它们仍然通过“样式”和“convert_options”作为图像处理。此外,现在我需要将一些文件存储在 S3 上,而将其他文件存储在本地。

也就是说,我一直在重组一些东西,现在我有一个 S3File、Contract 和其他模型,它们都继承自 Upload,而 Upload 仍然继承自 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

现在,当我在控制台中尝试查询数据时,它返回 Upload 对象,而不是 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">

将响应设为 Upload 类型是有问题的,因为它没有回形针附件。这些是在子类上定义的,每个子类都有一个唯一的 url、路径和has_attached_file 的存储定义。

我看到了 multiple models and paperclippolymorphic multiple models paperclip 问题,但在这些问题中,每个“多个模型”都继承自 ActiveRecord::Base,我的目标是尽可能避免这种情况,因为数据结构是相同的。

我的问题是:

  • 这是让文件类型具有各种存储后端和一个表的正确方法吗?作为文件,它们大多具有相同的属性,因此似乎没有必要为每个模型创建多个表。
  • 我需要使用多态关联吗?我将如何定义这些?我无法让它工作,而且它似乎不合适,因为 Contract 和 S3File 无论如何都是 Upload 类型,它们没有自己的表。
  • 使用单独的 has_attached_file(:item 或 :s3file)名称是个好主意,还是让它们保持相同是否有益?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 paperclip


    【解决方案1】:

    带回形针的 STI 已在多个问题 #293#601#605 中进行了讨论,并且现在是回形针的支持功能。

    STI 是正确的方法吗?

    在我的情况下这是正确的方法,因为我不想为每个模型使用多个表。为了解决在查询project.contracts 和获取Upload 类型类时出现错误类的问题,这是一个文档化的Rails 特性。只需将 class_name: "Contract 添加到模型上的 has_many 即可解决此问题:

    根据associations documentation on customizing the query

    自定义查询

    关联是从关系构建的,您可以使用关系 语法来自定义它们。例如,添加条件:

     class Blog < ActiveRecord::Base   
         has_many :published_posts, -> { where published: true }, class_name: 'Post' 
     end 
    

    是否需要多态关联

    在这种 STI 的情况下,没有。如果每个模型都有数据库支持,那么是的,多态关联可能会有所帮助。例如,请参阅polymorphic associations with multiple models 上的答案。

    使用同一个has_attached_file是个好主意

    自从上述拉取请求被合并以来,这在回形针中就不是问题了。可以覆盖子类中的选项、回调、样式、url 或路径,并享受 OOP 的好处以满足应用程序的需求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多