Rails和Carrierwave,保存具有不同扩展名的版本

时间:2017-02-16 22:51:47

标签: ruby-on-rails amazon-s3 carrierwave fog

我出于性能原因需要的是拇指版本保留了png格式和扩展名。格式似乎是正确的转换,但它一直保存带有.jpg扩展名的图像。

所以我有我的用户头像的代码:

class UserAvatarUploader < CarrierWave::Uploader::Base

    include CarrierWave::MiniMagick

    version :large do
        process resize_to_fit: [ 600, 600 ], convert: 'jpg'
    end

    version :small, from_version: :large do
        process resize_to_fill: [ 216, 216 ], convert: 'jpg'
    end

    version :thumb, from_version: :small do
        process resize_to_fill: [ 80, 80 ], convert: 'png'
    end

    version :tiny, from_version: :thumb do
        process resize_to_fill: [ 50, 50 ], convert: 'png'
    end

    def filename
        "#{secure_token}.#{file.extension}" if original_filename.present?
    end

    protected

    def secure_token
        var = :"@#{mounted_as}_secure_token"
        model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
    end

end

它保存了这样的图像:

  • cbc9418c-ffaa-49da-A530-f940d3da2868.jpg
  • large_cbc9418c-ffaa-49da-A530-f940d3da2868.jpg
  • small_cbc9418c-ffaa-49da-A530-f940d3da2868.jpg
  • thumb_cbc9418c-ffaa-49da-A530-f940d3da2868.jpg
  • tiny_cbc9418c-ffaa-49da-A530-f940d3da2868.jpg

即使我将整个代码更改为:

class UserAvatarUploader < CarrierWave::Uploader::Base

    include CarrierWave::MiniMagick

    version :large do
        process resize_to_fit: [ 600, 600 ], convert: :jpg
    end

    version :small do
        process resize_to_fill: [ 216, 216 ], convert: :jpg
    end

    version :thumb do
        process resize_to_fill: [ 80, 80 ], convert: :png
    end

    version :tiny do
        process resize_to_fill: [ 50, 50 ], convert: :png
    end

end

它一直用jpg扩展名保存图像, WTF

我对此感到疯狂,有什么建议吗?

更新

我已经尝试了下一个代码

class UserAvatarUploader < CarrierWave::Uploader::Base

    include CarrierWave::MiniMagick

    version :large do
        process resize_to_fit: [ 600, 600 ], convert: :jpg
    end

    version :small do
        process resize_to_fill: [ 216, 216 ], convert: :jpg
    end

    version :thumb do
        process resize_to_fill: [ 80, 80 ], convert: :png
    end

    version :tiny do
        process resize_to_fill: [ 50, 50 ], convert: :png
    end

    def filename
    "#{secure_token}.#{file.extension}" if original_filename.present?
    end

    protected

    def secure_token
        var = :"@#{mounted_as}_secure_token"
        model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
    end

end

然后将正确的图像上传到S3,然后user.avatar将所有版本保存为.jpg WTF !!!! 。现在发生的事情真的很奇怪......

控制台:

> user = User.find(id)
> user.avatar.recreate_versions!
> user.save!
> user.avatar.large.url
=> "http://bucket.s3.amazonaws.../large_96a1f5a4-cf07-490f-9711-618e04071950.jpg"
> user.avatar.small.url
=> "http://bucket.s3.amazonaws.../small_96a1f5a4-cf07-490f-9711-618e04071950.jpg"
> user.avatar.thumb.url
=> "http://bucket.s3.amazonaws.../thumb_96a1f5a4-cf07-490f-9711-618e04071950.png"
> user.avatar.tiny.url
=> "http://bucket.s3.amazonaws.../tiny_96a1f5a4-cf07-490f-9711-618e04071950.png"
> reload!
> user = User.find(id)
> user.avatar.large.url
=> "http://bucket.s3.amazonaws.../large_96a1f5a4-cf07-490f-9711-618e04071950.jpg"
> user.avatar.small.url
=> "http://bucket.s3.amazonaws.../small_96a1f5a4-cf07-490f-9711-618e04071950.jpg"
> user.avatar.thumb.url
=> "http://bucket.s3.amazonaws.../thumb_96a1f5a4-cf07-490f-9711-618e04071950.jpg"
> user.avatar.tiny.url
=> "http://bucket.s3.amazonaws.../tiny_96a1f5a4-cf07-490f-9711-618e04071950.jpg"

我讨厌你的承担

1 个答案:

答案 0 :(得分:1)

CarrierWave wiki上有一条条目:

  

还有另一个改变格式的方法。使用格式   方法只会更改tmp文件的名称。最终版本   该文件由载波命名,即使它创建的文件   将是具有正确mime的指定格式的真实文件   类型,它的扩展名不会被更改。我们需要使用   filename方法来设置它。

如果您想更改文件名,则应覆​​盖filename方法并添加扩展程序:

  def filename
    "#{secure_token}.#{file.extension}" if original_filename.present?
  end

您的问题依赖于多种格式,因此您可以覆盖版本块中的filename方法。

version :thumb do
    process resize_to_fill: [ 80, 80 ], convert: :png
    def filename
      "#{secure_token}.png" # I don't know if secure_token will be available here.
    end
end

如果这个pull request真的变成了掌握,你可能会忘记以上所有内容,只需将rename: true传递给现有的转换助手方法即可。至少看起来dev在描述拉取请求时会发生什么。