【问题标题】:Cannot retrieve Shrine metadata无法检索 Shrine 元数据
【发布时间】:2019-07-19 04:32:11
【问题描述】:

由于不推荐使用 Paperclip,我正在从 Paperclip 切换到 Shrine。

在我的模型Profilepic.rb 文件中,我用来检索图像变体的尺寸如下:

before_create  :save_ratio    

def save_ratio
    geo = Paperclip::Geometry.from_file(image.queued_for_write[:original])
    self.ratio = geo.width / geo.height
  end

基本上我正在保存图像的垂直比例。

它与 Paperclip 配合得很好:我抓取了临时图像 queued_for_write 并在保存值之前使用 Paperclip::Geometry 检查了尺寸。

在 Shrine 我已将以下内容添加到上传器:

plugin :add_metadata
plugin :store_dimensions

效果很好,因为我拥有所有可用信息并且图像已正确上传到 S3。

但我保存图像比例的新方法不再有效:

after_create  :save_ratio
def save_ratio
    self.ratio = self.image[:original].width.to_i / self.image[:original].height.to_i
  end

我明白了

错误未定义方法“[]” ProfilepicUploader::UploadedFile:0x00007f69a685c750>

而在控制台中,在创建图像之后:

Profilepic.first.image[:original].width.to_i

确实返回正确的值。

编辑

我的上传者:

require "image_processing/mini_magick"

class ProfilepicUploader < Shrine
    include ImageProcessing::MiniMagick
    plugin :processing
    plugin :validation_helpers # to validate image data
    plugin :versions
    plugin :add_metadata
    plugin :store_dimensions

    Attacher.validate do
        validate_max_size 5.megabyte
        validate_mime_type_inclusion ['image/jpg', 'image/jpeg', 'image/png']
    end

    process(:store) do |io, context|
        versions = { original: io } # retain original

        io.download do |original|
            pipeline = ImageProcessing::MiniMagick.source(original)

            versions[:editable]  = pipeline.resize_to_fit!(700, 700)
            versions[:thumbnail] = pipeline.resize_to_fill!(400, 400)
            versions[:small]  = pipeline.resize_to_fill!(200, 200)
        end

        versions # return the hash of processed files
    end

end

我的模型:

class Profilepic < ApplicationRecord
  require "image_processing/mini_magick"
  belongs_to :professionnel
  before_create :set_hashid

  include ProfilepicUploader::Attachment.new(:image) # adds an `image` virtual attribute
  include ProfilepicFinalUploader::Attachment.new(:final_image) # adds an `image` virtual attribute


 attr_accessor :crop_x, :crop_y, :crop_w, :crop_h   

 after_create  :save_ratio_image   

private

  def save_ratio
    self.ratio = self.image[:original].width.to_i / self.image[:original].height.to_i
  end

end

【问题讨论】:

    标签: ruby-on-rails paperclip ruby-on-rails-5.2 shrine


    【解决方案1】:

    Shrine 首先将记录与缓存文件一起保存,然后再次与存储的处理文件一起保存。您收到错误的原因是因为您的代码在分配缓存文件时首先运行,此时尚未完成任何处理,self.image 是单个上传文件(不是上传文件的哈希) .

    您可能想要的是已经从 缓存 文件(与处理后的:original 上传的文件相同)中提取比率:

    def save_ratio
      if image_data_changed? && image_attacher.cached?
        self.ratio = image.width.to_f / image.height.to_f
      end
    end
    

    或者,您可以创建 image_widthimage_height 列,并让 Shrine 使用 widthheight 元数据自动填充它们,然后稍后在 SQL 中计算配给。

    class ProfilepicUploader < Shrine
      plugin :metadata_attributes, width: :width, height: height
    end
    

    正如在另一个答案的 cmets 中提到的,您还可以将 JSONB 列用于附件列,这样您也可以使用 SQL 获取 widthheight 元数据。

    【讨论】:

    • 非常感谢。实际上,我在视图中进行了计算,而不是在模型中进行了计算,因为我不确定创建记录时模型中可用的内容(Json 显然还没有准备好)。只有当图像准备好时才能访问视图......这修复了 pb.此外,Andre 在上传器中获取上下文的答案可能是正确的(由于to_i 而不是to_f,我得到了错误的比率)但我更喜欢将上传器数据和模型数据保留在各自的范围内..
    • 实际上我已经从缓存文件中实现了您的解决方案。它完美地工作。谢谢
    【解决方案2】:

    我的 2 美分:

    如果您使用 Shrine::Attach.promote 在后台处理文件,通过作业或工作人员,versions 元数据可能在那时(after_create 回调时间)不可用。

    我不确定解决此问题的最佳方法是什么,但您可以通过上下文 (https://github.com/shrinerb/shrine/blob/v2.16.0/doc/processing.md#processing-on-upload) 访问处于处理阶段的模型:

    class SomeUploader < Shrine
      process(:store) do |io, context|
        ratio = io.metadata["width"] / io.metadata["height"]
        model = context[:record]
        model.update(ratio: ratio)
    
        versions = { original: io } # retain original
        io.download do |original|
          pipeline = ImageProcessing::MiniMagick.source(original)
          versions[:small]  = pipeline.resize_to_limit!(300, 300)
          # ....
        end
        versions
      end
    end
    

    【讨论】:

    • 谢谢,我会试试你的解决方案。目前我尝试实现这是模型。也许从上传者那里做就可以了。很难理解 Uploader 与 Shrine 的实际模型的范围。我将尝试通过rails应用程序,S3,上传器的实际过程和路径找到一个资源..
    • 实际上您的链接退出解释了这一点。我会尝试深入了解它。
    • 您仍然可以通过 image_data 属性访问该回调中的宽度和高度
    • 我从不需要解析 JSON 内容,我不了解您的模型,但如果创建了 JSON / JSONB 列(在 postgreSQL 中),则哈希已在您的模型中序列化;请记住,红宝石中的 (1/2 ==0) ;您可能需要转换为浮点数以满足您的需求
    • 仅供参考,Shrine 返回整数的宽度和高度,因此您需要在除法之前将它们转换为浮点数。
    猜你喜欢
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    相关资源
    最近更新 更多