Active Storage 文件上传回调

Tom*_*oma 11 ruby ruby-on-rails rails-activestorage

模型上的活动存储文件是否有回调

after_update或者after_save当模型上的字段发生更改时被调用。但是,当您更新(或者更确切地说上传新文件)时,似乎没有调用回调?

语境:

class Person < ApplicationRecord
  #name :string
  has_one_attached :id_document

  after_update :call_some_service

  def call_some_service
    #do something
  end
end
Run Code Online (Sandbox Code Playgroud)

id_document当上传新内容时after_update不会调用,但是当name人员更改时after_update会执行回调

Tom*_*oma 1

@Uleb 的答案让我完成了 90% 的工作,但为了完整起见,我将发布我的最终解决方案。

我遇到的问题是我无法对类进行猴子修补(不知道为什么,甚至按照 @user10692737 要求该类也没有帮助)

所以我复制了源代码(https://github.com/rails/rails/blob/fc5dd0b85189811062c85520fd70de8389b55aeb/activestorage/app/models/active_storage/attachment.rb#L20

并修改它以包含回调

require "active_support/core_ext/module/delegation"

# Attachments associate records with blobs. Usually that's a one record-many blobs relationship,
# but it is possible to associate many different records with the same blob. If you're doing that,
# you'll want to declare with <tt>has_one/many_attached :thingy, dependent: false</tt>, so that destroying
# any one record won't destroy the blob as well. (Then you'll need to do your own garbage collecting, though).
class ActiveStorage::Attachment < ActiveRecord::Base
  self.table_name = "active_storage_attachments"

  belongs_to :record, polymorphic: true, touch: true
  belongs_to :blob, class_name: "ActiveStorage::Blob"

  delegate_missing_to :blob

  #CUSTOMIZED AT THE END:
  after_create_commit :analyze_blob_later, :identify_blob, :do_something

  # Synchronously purges the blob (deletes it from the configured service) and destroys the attachment.
  def purge
    blob.purge
    destroy
  end

  # Destroys the attachment and asynchronously purges the blob (deletes it from the configured service).
  def purge_later
    blob.purge_later
    destroy
  end


  private
    def identify_blob
      blob.identify
    end

    def analyze_blob_later
      blob.analyze_later unless blob.analyzed?
    end

    #CUSTOMIZED:
    def do_something

    end
end
Run Code Online (Sandbox Code Playgroud)

不确定这是最好的方法,如果我找到更好的解决方案,我会更新