Activestorage Светильники вложения - PullRequest
0 голосов
/ 21 мая 2018

В испытаниях рельсов.У меня есть базовая модель с только activestorage:

class User < ApplicationRecord
  has_one_attached :avatar
end

Я пытаюсь сделать это приспособление, но мне не везет (у меня там есть изображение):

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

Как правильно прикрепить файл аватара через приспособления?

Ответы [ 3 ]

0 голосов
/ 16 ноября 2018

IS04 потерял комментарий к единственному ответу, на котором я просто хочу остановиться.

Я застрял, пытаясь сделать это некоторое время, и после ответа iGian мне это помогло.Однако моя команда проверила мой PR и спросила, почему я представляю новые модели, так близко названные для собственных моделей ActiveStorage (то есть ActiveStorage::Attachment и ActiveStorage::Blob).

Затем мне пришло в голову, что все, что мне нужно было сделать, этопереместите прибор из active_storage_attachments.yml в active_storage/attachments.yml.

Другая часть, которую мне пришлось выяснить при дополнительном исследовании, - это как использовать эти приборы с автоматически генерируемыми идентификаторами.Что я и сделал, используя ActiveRecord::FixtureSet.identify так:

attachment_identifier:
  name: "attachment_name"
  record_type: "MyRecordClass"
  record_id: <%= ActiveRecord::FixtureSet.identify(:my_record_identifier) %>
  blob_id: <%= ActiveRecord::FixtureSet.identify(:blob) %>
  created_at: <%= Time.zone.now %>
0 голосов
/ 24 апреля 2019

Это намного проще, чем кто-либо делает.Я не хочу унижать кого-либо, поскольку мне потребовалось некоторое время, чтобы понять это на основе этих ответов.Я собираюсь использовать ту же модель данных, чтобы упростить ее.

У пользователя есть один прикрепленный «аватар».Допустим, у вас есть это пользовательское приспособление:

# users.yml
one:
  name: Fred

Вот все, что вам нужно сделать:

% mkdir test/fixtures/active_storage

Теперь вы просто помещаете "attachments.yml" и "blobs.yml" вэтот каталог.Запись «вложения» будет ссылаться на BLOB-объект, а также на пользователя:

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

и

# 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==

Теперь это «сработает», чтобы иметь прикрепленное изображение.Если вам нужен сам файл, сначала посмотрите в config / storage.yml, чтобы узнать, по какому пути хранятся файлы. По умолчанию это «tmp / storage».Файл выше будет храниться здесь:

tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A

Чтобы вычислить контрольную сумму, см. Здесь:

Как вычисляется контрольная сумма в таблице BLOB-объектов для рельсов ActiveStorage

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

Можно было бы заполнить размер файла и контрольную сумму, используя erb в приспособлении:

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

Обратите внимание, что сначала необходимо скопировать файл в каталог хранилища.

0 голосов
/ 03 июня 2018

Допустим, у вас есть тест для пользователя модели, по умолчанию UserTest#test_the_truth

rails test test/models/user_test.rb

Я полагаю, вы получаете ошибку Errno::ENOENT: No such file or directory @ rb_sysopen во время теста из-заошибка в вашем пути, вы должны добавить 'fixtures', она должна выглядеть следующим образом:

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

, но теперь у вас должна быть эта ошибка: ActiveRecord::Fixture::FixtureError: table "users" has no column named "avatar".

Это правильно, потому что ActiveStorage используетдве таблицы для работы: active_storage_attachments и active_storage_blobs.

Итак, вам нужно удалить столбец аватара из users.yml и добавить два новых файла:

# active_storage_attachments.yml
one:
  name: 'avatar'
  record_type: 'User'
  record_id: 1
  blob_id: 1

и

# active_storage_blobs.yml
one:
  id: 1
  key: '12345678'
  filename: 'file.png'
  content_type: 'image/png'
  metadata: nil
  byte_size: 2000
  checksum: "123456789012345678901234"

Кроме того, в App/models добавьте , даже если это не требуется для работы ActiveStorage .

# active_storage_attachment.rb
class ActiveStorageAttachment < ApplicationRecord
end

и

# active_storage_blob.rb
class ActiveStorageBlob < ApplicationRecord
end

Тогда UserTest#test_the_truth удастся.

Но лучше избавиться от active_storage_attachment.rb и active_storage_blob.rb и следовать другому способу проверки.

Для проверки, является ли вложениерабочий, лучше протестируйте контроллер , например добавив этот код в test/controllers/users_controller_test.rb:

require 'test_helper'

class UserControllerTest < ActionController::TestCase
  def setup
    @controller = UsersController.new
  end
  test "create user with avatar" do
    user_name = 'fake_name'
    avatar_image = fixture_file_upload(Rails.root.join('test', 'fixtures', 'files', 'avatar.png'),'image/png')
    post :create, params: {user: {name: user_name, avatar: avatar_image}}
  end
end

Проверьте папку tmp/storage, должна быть пустой.

Launchтест с: rails test test/controllers/users_controller_test.rb

Это должно завершиться успешно, тогда, если вы вернетесь в tmp/storage, вы найдете несколько папок и файлов, сгенерированных тестом.

Редактируйте после комментариев: Если вынужно проверить обратные вызовы на User модели, тогда это должно работать:

# rails test test/models/user_test.rb

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  test "should have avatar attached" do
    u = User.new
    u.name = 'Jim Kirk'
    file = Rails.root.join('test', 'fixtures', 'files', 'image.png')
    u.avatar.attach(io: File.open(file), filename: 'image.png') # attach the avatar, remove this if it is done with the callback
    assert u.valid?
    assert u.avatar.attached? # checks if the avatar is attached
  end
end

Я не знаю ваш обратный вызов, но я надеюсь, что это дает вам некоторую подсказку.

...