【问题标题】:Attaching ActiveStorage files in factorybot在 factorybot 中附加 ActiveStorage 文件
【发布时间】:2019-08-04 02:38:28
【问题描述】:

我正在寻找一种方法来为具有活动存储附件的模型创建工厂

我尝试了this post中的方法

我的工厂

factory :activity_fit_file, class: 'Activity' do
    association :user, factory: :user
    activity_type {:cycling}
    original_activity_log_file { fixture_file_upload("#{Rails.root}/spec/files/example_fit_file.fit") }
end

但我收到了这个错误

 NoMethodError:
   undefined method `fixture_file_upload' for #<FactoryBot::SyntaxRunner:0x000000000208c5f8>

在 ActiveStorage 中附加文件的正确方法是什么?

【问题讨论】:

    标签: ruby-on-rails rspec factory-bot rails-activestorage


    【解决方案1】:

    直接用Rack::Test::UploadedFile试试:

    file { Rack::Test::UploadedFile.new('path', 'image/png') }
    

    【讨论】:

    • undefined method upload' for nil:NilClass # /home/user/.rvm/gems/ruby-2.5.1/gems/activestorage-5.2.0/app/models/active_storage/blob.rb:155:in upload'
    • 可能是文件路径,试试spec/files/example_fit_file.fit
    • 好的,这是解决方案,但我忘了在我的测试环境中设置 config.active_storage.service
    • 这为我工作了多年,但在更新到 Rails 6.1.3 后,它得到了一个ActiveStorage::IntegrityError 错误。也没有太多关于该错误的信息。
    • @Archonic 我知道这已经有一段时间了,但是您是否弄清楚在这种情况下导致ActiveStorage::IntegrityError 的原因是什么?我突然开始在使用 Rails 5.2.0 的项目中看到它。宝石和配置最近也没有改变。
    【解决方案2】:

    此解决方案适用于 rails 6:

    factory :post do
      # ...
      after(:build) do |post|
        post.image.attach(
          io: File.open(Rails.root.join('test', 'fixture_files', 'test.jpg')),
          filename: 'test.jpg',
          content_type: 'image/jpeg'
        )
      end
    end
    

    【讨论】:

    • 这应该是 Rails 6+ 公认的解决方案。请注意,您还可以使用 FactoryBot transient attributes 将与附件相关的信息传递给您的模型,例如after(:build) { |item, ev| item.image.attach(io: File.open(ev.image_path, 'rb'), filename: File.basename(ev.image_path), content_type: MiniMime.lookup_by_filename(ev.image_path)) if ev.image_path }
    • 我可以确认这是可行的。在几个月没有错误后突然使用Rack::Test::UploadedFile 方法获得ActiveStorage::IntegrityError 后,我切换到了这个:耸耸肩:
    【解决方案3】:

    将您的代码更改为以下内容即可。

    include ActionDispatch::TestProcess
    factory :activity_fit_file, class: 'Activity' do
        association :user, factory: :user
        activity_type {:cycling}
        original_activity_log_file { fixture_file_upload("#{Rails.root}/spec/files/example_fit_file.fit") }
    end
    

    【讨论】:

    猜你喜欢
    • 2021-05-02
    • 2019-02-18
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 2019-04-23
    相关资源
    最近更新 更多