在一个应用程序中,我想通过after_create
回调函数将公共文件的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?
请注意,这是一个自我回答的问题,我只是想分享我的经验。
2条答案
按热度按时间tf7tbtn21#
我的解决方案是使用
after_commit ..., on: :create
回调函数而不是after_create
:答案是显而易见的,尽管我浪费了很长时间来绕着它打转。解释很简单:
after_commit
回调仅在所有信息成功持久化后触发。在我的例子中,文件尚未持久化到存储目录(在after_create
阶段)-这就是为什么我得到了临时文件的URL而不是实际的URL。希望这对某些人有所帮助并节省他们的时间。5jvtdoz22#
使用Rails 7.0.4和carrierwave 2.0,使用
after_commit :foo, on: :create
回调仍然为我返回临时路径。使用Carrierwave callbacks,特别是在uploader类本身中使用
after :store, :foo
,可以确保获取文件URL的调用只在文件上传到云存储之后发生。注:
foo
方法需要一个参数才能工作。在本例中,使用未使用的_new_file
参数。model
指向上载程序所连接到的示例对象。