活动存储文件上传的回调

时间:2018-11-09 13:02:35

标签: ruby-on-rails ruby rails-activestorage

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

更改模型上的字段时,将调用

after_updateafter_save。但是,当您更新(或上传新文件)时,似乎没有调用回调吗?

上下文:

class Person < ApplicationRecord
  #name :string
  has_one_attached :id_document

  after_update :call_some_service

  def call_some_service
    #do something
  end
end

上载新的id_document时,不会调用after_update,但是如果更改了该人的name,则会执行after_update回调

4 个答案:

答案 0 :(得分:1)

目前看来,这种情况下没有回调。

您可以做的是创建一个模型来处理活动存储附件的创建,这是将文件附加到个人模型时创建的。

因此创建一个新模型

class ActiveStorageAttachment < ActiveRecord::Base
  after_update :after_update

  private
  def after_update
    if record_type == 'Person'
      record.do_something
    end
  end
end

您通常已经在数据库中创建了模型表,因此无需迁移,只需创建此模型即可。

答案 1 :(得分: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

不确定其最佳方法,如果我找到更好的解决方案,它将更新

答案 2 :(得分:0)

我只发表评论,但由于没有代表,这是不可能的。

Uelb的答案有效,但您需要修复注释中的错误,并将其添加为初始值设定项而不是模型。例如:

require 'active_storage/attachment'

class ActiveStorage::Attachment
  before_save :do_something

  def do_something
    puts 'yeah!'
  end
end

答案 3 :(得分:0)

在我的情况下,跟踪附件时间戳有效

class Person < ApplicationRecord
  has_one_attached :id_document

  after_save do    
    if id_document.attached? && (Time.now  - id_document.attachment.created_at)<5
      Rails.logger.info "id_document change detected"
    end
  end
end