在 factorybot 中附加 ActiveStorage 文件

Posted

技术标签:

【中文标题】在 factorybot 中附加 ActiveStorage 文件【英文标题】:Attaching ActiveStorage files in factorybot 【发布时间】: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 中附加文件的正确方法是什么?

【问题讨论】:

【参考方案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

【讨论】:

不建议包含ActionDispatch::TestProcess,因为它包含其他方法,例如#session,这些方法会覆盖所有对象上的现有方法。见:github.com/honeybadger-io/honeybadger-ruby/blob/… 和这个***.com/a/23220853/1296731

以上是关于在 factorybot 中附加 ActiveStorage 文件的主要内容,如果未能解决你的问题,请参考以下文章

将帮助文件加载到 FactoryBot 文件中会导致“无法加载此类文件”[重复]

FactoryBot拒绝与协会建立工厂

如何通过 has_many 关联在 FactoryBot 中设置工厂

从FactoryGirl更新到factoryBot会导致NoMethodError

markdown Factorybotいろいろ

FactoryGirl / Bot图像定义