ruby-on-rails 回调活动存储文件上载

vyswwuz2  于 2022-11-19  发布在  Ruby
关注(0)|答案(6)|浏览(126)

模型上的活动存储文件是否有回调
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回调

5vf7fwbs

5vf7fwbs1#

目前看来,这个案子没有回调。
您可以做的是创建一个模型来处理活动存储附件的创建,该附件是在您将文件附加到您的个人模型时创建的。
因此创建一个新模型

class ActiveStorageAttachment < ActiveRecord::Base
  after_update :after_update

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

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

ikfrs5lh

ikfrs5lh2#

嗯,我只是想评论一下,但因为这是不可能的,没有代表。
Uelb的答案是可行的,但是你需要修复注解中的错误,并将其作为初始化器而不是模型添加。

require 'active_storage/attachment'

class ActiveStorage::Attachment
  before_save :do_something

  def do_something
    puts 'yeah!'
  end
end
hfsqlsce

hfsqlsce3#

在我的情况下,跟踪附件时间戳工作

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
xv8emn3q

xv8emn3q4#

来自@Uleb的答案让我完成了90%的工作,但为了完成起见,我将发布我的最终解决方案。
我遇到的问题是,我不能猴子补丁类(不知道为什么,即使要求类按照@user10692737没有帮助)
所以我复制了源代码(http://github.com/rails/rails/blob/fc 5dd 0 b85189811062 c85520 fd 70 de 8389 b55 aeb/活动存储/应用程序/模型/活动存储/附件. 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

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

ilmyapht

ilmyapht5#

我所做的就是在我的记录中添加回拨:

after_touch :check_after_touch_data

如果添加、编辑或删除ActiveStorage对象,则调用此回调函数。我使用此回调函数检查是否有更改。

9avjhtql

9avjhtql6#

这些都没有真正击中要害,但您可以通过以下博客文章https://redgreen.no/2021/01/25/active-storage-callbacks.html实现您所寻找的目标
我能够修改代码来处理附件而不是像这样的blob

Rails.configuration.to_prepare do
  module ActiveStorage::Attachment::Callbacks
    # Gives us some convenient shortcuts, like `prepended`
    extend ActiveSupport::Concern

    # When prepended into a class, define our callback
    prepended do
      after_commit :attachment_changed, on: %i[create update]
    end

    # callback method
    def attachment_changed
      record.after_attachment_update(self) if record.respond_to? :after_attachment_update
    end
  end

  # After defining the module, call on ActiveStorage::Blob to prepend it in.
  ActiveStorage::Attachment.prepend ActiveStorage::Attachment::Callbacks
end

相关问题