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 而不是实际文件的原因。希望这对某人有所帮助并节省他们的时间。
在应用程序中,我想在 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 而不是实际文件的原因。希望这对某人有所帮助并节省他们的时间。