【问题标题】:Migrating Carrierwave to ActiveStorage将 Carrierwave 迁移到 ActiveStorage
【发布时间】:2018-09-27 02:41:47
【问题描述】:

我有一个使用 Carrierwave 处理文件上传的应用程序,但我非常喜欢 ActiveStorage 的简单性。有很多关于从 Paperclip 迁移到 ActiveStorage 的教程以及以前的日落开发,但我看不到从 Carrierwave 迁移到 ActiveStorage 的任何内容。有没有人成功完成迁移并能指出我正确的方向?

【问题讨论】:

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


    【解决方案1】:

    过程其实很简单。

    第 1 步:

    配置活动存储桶。尝试使用与您的carrierwave one不同的存储桶

    第二步:

    配置您的模型以提供对 ActiveStorage 的访问。例子

     class Photo < AR::Base
    
       mount_uploader :file, FileUploader # this is the current carrierwave implementation. Don't remove it 
    
       has_one_attached :file_new # this will be your new file 
    
     end
    

    现在您将有两个相同模型的实现。载波访问 file 和 ActiveStorage file_new

    第三步:

    从 Carrierwave 下载图像并将其保存到活动存储中 这可以在 rake 文件、activeJob 等中实现。

     Photo.find_each do |photo|
       begin
       filename = File.basename(URI.parse(photo.fileurl))
       photo.file_new.attach(io: open(photo.file.url), filename: d.file )
       rescue => e
       ## log/handle your errors in order to retry later
       end
     end
    

    此时,您将在carrierwave 存储桶上拥有一张图像,在活动存储桶上拥有新创建的图像!

    (可选)

    第四步

    一旦您准备好迁移,请修改您的模型,更改活动存储访问器并删除载波集成

     class Photo < AR::Base
       has_one_attached :file # we changed the atachment name from file_new to file 
     end
    

    这是一个方便的选项,因此您在控制器和其他地方的集成保持不变。希望!

     第 5 步

    更新您在active_storage_attachments 表上的记录,以便将附件作为file 而不是file_new 更新列name 从“file_new”到“file”

    注释

    可以对应用程序进行一些其他调整以处理需要考虑的事情

    • 如果您的网站将在您进行迁移时运行,则一种完全运行的方法是为新上传的内容实施主动存储,那么当您显示图像时,您可以将主动存储和carrierwave 显示为后备

    helper 中的类似内容:

    photo.attached? ? url_for(photo.file_new) : photo.file.url

    我希望这会有所帮助!

    【讨论】:

    • 那个 rake 任务比我开始做的要简单得多,谢谢。我会试一试,然后告诉你进展如何。
    • 建议的 rake 任务有问题。按原样运行它会给我以下错误消息: (bad URI(is not URI?): nyc3.digitaloceanspaces.com***/***/***.jpg) 虽然我知道图像在那里。事实上,如果我在浏览器中打开指定的链接,我可以选择下载它。我修改了代码以在解析之前先对 uri 进行编码,然后收到 #' 的“未定义方法 'gsub”,但上传器中未使用 gsub。
    • def store_dirif Rails.env.development?"development/#{model.class.to_s.underscore}/#{model.slug.to_s}"else"#{model.class.to_s.underscore}/#{model.slug.to_s}"endend
    • 我有点业余,不确定第 3 步。我该如何运行它? rake 文件和 ActiveJobs 超出了我的知识范围。好的,导游很好。我跑了bin/rails generate job copy-carrierwave-to-activestorage。我想我可以使用您的Photo.find…,但对我来说将其放入哪个文件以及在我完成后如何运行它并不明显。这些文件是 app/jobs/copy_carrierwave_to_activestorage_job.rbspec/jobs/copy_carrierwave_to_activestorage_job_spec.rbapp/jobs/application_job.rb。我很欣赏这篇文章,在迁移方面没有看到任何其他内容。
    • 你真的试过你的代码吗?我相当于你的步骤#3 photo.file_new.attach() 中的 attach() 行崩溃:NoMethodError (undefined method 'upload' for nil:NilClass)。 blob 未签名似乎有问题?如果有人有可行的解决方案,请分享。
    【解决方案2】:

    开始

    1. 你必须运行这个bundle exec rails active_storage:install
    2. rails db:migrate
    3. 在您的模型中替换 mount_uploader :image, ImageUploader,使其看起来像 has_one_attached :image
    4. 要在视图中渲染图像,应将image_url 替换为url_for(user.image)

    您不必对控制器代码或参数进行任何更改,因为属性image 已经是一个strong参数。

    # user.rb
    class User < ApplicationRecord
      # mount_uploader :image, ImageUploader
    
      has_one_attached :image
    end
    
    # show.html.erb
    <%= image_tag url_for(user.image) %>
    or
    <%= image_tag user.image %>
    

    【讨论】:

    • 感谢您的回复。对于我已经完成的初始设置绝对有用,但我希望将现有记录从 Carrierwave 迁移到 ActiveStorage。
    • 您是否将图像存储在云上,诸如 s3 之类的服务?
    • 其实是数字海洋,但它确实使用了 s3 sdk。
    • 如果我们已经通过 S3 在 Heroku 上部署了数千个文件上传怎么办?如何管理这种类型的转移?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多