Paperclip 没有为一种模型存储替代尺寸,但为另一种模型存储了替代尺寸

Paperclip is not storing alternative sizes for one model, but does for another

我有两个附有图片的模型。第一个是这样定义的:

class Post < ActiveRecord::Base
  has_attached_file :cover_image, styles: { large: "750x750^", medium: "600x600>", thumb: "100x100>" }, default_url: ":style/missing.gif"
  validates_attachment_content_type :cover_image, content_type: /\Aimage\/.*\Z/
end

这非常有效,在我的 /public 文件夹中总共存储了 4 张图像。

不过我的第二个模型...

class Lesson < ActiveRecord::Base
  has_attached_file :image, styles: { large: "750x750^", medium: "600x600>", thumb: "100x100>" }, default_url: ":style/missing.gif"
  validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end

...仅将原始图像存储在名为 original 的文件夹中。

我的服务器日志确实在 POST 请求中显示类似这样的内容:

Command :: file -b --mime '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-jxf7m7.jpg'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]'
Command :: convert '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]' -auto-orient -resize "750x750^" '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/a802cd21677cc830b7ba993a8ff7edd920151207-39937-1p9h15m'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]'
Command :: convert '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]' -auto-orient -resize "600x600>" '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/a802cd21677cc830b7ba993a8ff7edd920151207-39937-r4bxgl'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]'
Command :: convert '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-wmm770.jpg[0]' -auto-orient -resize "100x100>" '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/a802cd21677cc830b7ba993a8ff7edd920151207-39937-4zvubq'
Command :: file -b --mime '/var/folders/2b/q6z4f1fn58s83fbx77xwsk5h0000gn/T/64ecce8dbf7049731a63696ae4d7933020151207-39937-19vrckc.jpg'

会不会是字段名引起的?还有其他想法吗?

编辑 我的课程模型实际上有点复杂,因为它使用共享 table 来区分内容类型:

class Lesson < ActiveRecord::Base
  self.table_name = 'steps'
  default_scope { where(content_type: name) }
  has_attached_file :cover_image, styles: { large: "750x750^", medium: "600x600>", thumb: "100x100>" }, default_url: ":style/missing.gif"
  validates_attachment_content_type :cover_image, content_type: /\Aimage\/.*\Z/

  validates :title, presence: true, length: { maximum: 255 }

  def self.create_for_course(course, attributes = {})
    content = new(attributes)
    if content.valid?
      step = Step.create(content_type: name, course: course)
      instance = step.becomes(self)
      instance.update_attributes(attributes)
      instance
    else
      step = content.becomes(Step)
      step.course = course
      step.content_type = name
      step.becomes(self)
    end
  end
  #include Content
  #restrict_attrs :title, :content_body, :cover_image_file_name, :cover_image_content_type, :cover_image_file_size, :cover_image_updated_at, :cover_image

end

这篇评论太长了;您将受益于使用 paperclip_defaults 选项:

#config/application.rb
...
config.paperclip_defaults = {
   styles: { large: "750x750^", medium: "600x600>", thumb: "100x100>" },     
   default_url: ":style/missing.gif"
} 

这将允许您在模型中调用附件名称 并且 如果您愿意,可以覆盖默认值:

#app/models/post.rb
class Post < ActiveRecord::Base
  has_attached_file :cover_image
  validates_attachment_content_type :cover_image, content_type: /\Aimage\/.*\Z/
end

--

关于您的错误,我不确定问题出在哪里。

不过我有一个建议。这有点棘手,但如果你能让它工作,它会让你所有的模型都超级干燥。

Here's a link:

#app/models/asset.rb
class Asset < ActiveRecord::Base
    #Associations
    ##################
    belongs_to :assetable, polymorphic: true

    #Paperclip
    ##################
    delegate :url, to: :attachment

########################################

    ##################
    #     Methods    #
    ##################
    before_create :dimensions #-> https://github.com/thoughtbot/paperclip/wiki/Extracting-image-dimensions

    #Width & Height
    def dimensions
        return unless image? && has_dimensions?
        self.width  = geometry.width
        self.height = geometry.height
    end

    ########

    private

    #Geometry -> https://github.com/galetahub/ckeditor/blob/master/lib/ckeditor/backend/paperclip.rb#L23
    def geometry
        @geometry ||= begin
            file = attachment.respond_to?(:queued_for_write) ? attachment.queued_for_write[:original] : attachment.to_file
            ::Paperclip::Geometry.from_file(file)
        end
    end

    #Image?
    def image?
        image_types = %w(image/jpeg image/png image/gif image/jpg image/pjpeg image/tiff image/x-png)
        image_types.include? attachment_content_type
    end

    #Dimensions
    def has_dimensions?
        respond_to?(:width) && respond_to?(:height)
    end
end

资产table:

这可以与 STI 一起使用:

#app/models/post.rb
class Post < ActiveRecord::Base
    has_one :cover, class_name: "Post::Cover", as: :assetable, dependent: :destroy
    accepts_nested_attributes_for :cover, reject_if: :all_blank
   has
end

#app/models/post/cover.rb
class Post::Cover < Asset
   has_attached_file :attachment
end

这允许您将 cover 属性设置为嵌套关联,但还有一个额外的好处,即可以将应用中的所有资产存储在 assets table 中:

--

更新

您可以使用以下方法使您的 create_for_course 方法更干燥:

#app/models/post.rb
class Lesson < ActiveRecord::Base
   attr_reader :course

   belongs_to :step
   before_create :set_step, if Proc.new { |a| a.course }

   private

   def set_step
      self.step.create(course: course) #-> we can use the course virtual attribute)
   end
end 

尽管我怀疑它是否专门捕获了您的功能,但它 允许您 运行:

lesson = Lesson.create course: "5"
# automatically creates "step" with course of "5" and current lesson