Carrierwave returns tmp 文件的路径而不是回调中的实际路径

Carrierwave returns path of tmp file instead of actual in a callback

在应用程序中,我想在 after_create 回调中将 public 文件 URL 发送到服务。因此,代码(简化)如下所示:

class UserProfile < ApplicationRecord
  mount_uploader :video, VideoUploader
  after_create :send_url_to_service

  private

  # Just logs the URL
  def send_url_to_service
    Rails.logger.info video.url
  end
end

令我沮丧的是,上传后,send_url_to_service 回调总是记录缓存的文件路径 - 类似于 'uploads/tmp/1473900000-123-0001-0123/file.mp4' 而不是 'uploads/user_profiles/video/1/file.mp4'。我尝试编写一种方法来从实际文件路径形成 URL,但它不起作用,因为该文件还不存在。

所以,问题是,在这种情况下,如何获得最终文件URL?

P。 S. 请注意,这是一个自我回答的问题,我只是想分享我的经验。

我的解决方案是使用 after_commit ..., on: :create 回调而不是 after_create:

class UserProfile < ApplicationRecord
  mount_uploader :video, VideoUploader
  after_commit :send_url_to_service, on: :create

  private

  # Just logs the URL
  def send_url_to_service
    Rails.logger.info video.url
  end
end

答案很明显,虽然我浪费了很长时间在它周围徘徊。解释很简单:after_commit回调仅在所有信息成功持久化后触发。在我的例子中,文件还没有保存到存储目录(在 after_create 阶段)——这就是为什么我得到临时文件 url 而不是实际文件的原因。希望这对某人有所帮助并节省他们的时间。