Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
638 views
in Technique[技术] by (71.8m points)

ruby on rails - Activestorage fixtures attachments

In rails tests. I have a basic model with only activestorage:

class User < ApplicationRecord
  has_one_attached :avatar
end

I'm trying to make it's fixture, but having no luck with (I do have an image there):

# users.yml
one:
  avatar: <%= File.open Rails.root.join('test', 'files', 'image.png').to_s %>

How do I properly attach an avatar file through fixtures?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is far easier than anybody is making it out to be. I don't mean to demean anybody, as it took me some time to figure this out based on these answers. I'm going to use the same data model to make it easy.

User has one attached "avatar". Let's say you have this users fixture:

# users.yml
fred:
  name: Fred

Here's all you need to do:

% mkdir test/fixtures/active_storage

Now, you just put "attachments.yml" and "blobs.yml" in that directory. The "attachment" record will reference the blob as well as the user:

# active_storage/attachments.yml
freds_picture:
  name: avatar
  record: fred (User)
  blob: freds_picture_blob

and

# active_storage/blobs.yml
freds_picture_blob:
  key: aabbWNGW1VrxZ8Eu4zmyw13A
  filename: fred.jpg
  content_type: image/jpeg
  metadata: '{"identified":true,"analyzed":true}'
  byte_size: 1000
  checksum: fdUivZUf74Y6pjAiemuvlg==
  service_name: local

The key is generated like this in code:

ActiveStorage::Blob.generate_unique_secure_token

You can run that in the console to get a key for the above fixture.

Now, that will "work" to have an attached picture. If you need the actual file to be there, first look in config/storage.yml to see what path the files are stored in. By default, it's "tmp/storage". The file above will be stored here:

tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A

To calculate the checksum, see here:

How is the checksum calculated in the blobs table for rails ActiveStorage

md5_checksum = Digest::MD5.file('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A').base64digest

It would be possible to fill in the file size and checksum using erb in the fixture:

  byte_size: <%= File.size('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A') %>
  checksum: <%= Digest::MD5.file('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A').base64digest %>

Note that you have to copy the file into the storage directory first. The storage root directory for the test environment is tmp/storage/ by default, with the remaining path constructed from the first four characters of the key (i.e. tmp/storage/aa/bb).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...