#ruby-on-rails #ruby-on-rails-6 #activemodel
Вопрос:
У меня есть приложение Rails 6.
User has_one Shop
Shop has_one_attached Logo
User.update
с nested_attributes
чистками то User.shop.company_logo
.
class User
has_one :shop, dependent: :destroy # delete Shop if user gets deleted
accepts_nested_attributes_for :shop, # also tried reject_if: :all_blank
end
class Shop
belongs_to :user
has_one_attached :company_logo do |attachable|
attachable.variant :thumbnail, resize_to_fill: [100, 100]
end
end
# creating a User
User.create({name: "Test"})
# creating a Shop
logo = File.open(Rails.root.join('spec', 'fixtures', 'files', '400x400.png'))
Shop.create(user_id: User.last.id, name: "TestShop", company_logo: logo)
User.last.shop.company_logo.attached? # returns TRUE !!!
# Update User (deletes / detaches company_logo)
params = {name: "TestUpdateName", shop: {name: "TestUpdateShop"}}
User.last.update(params)
User.last.shop.company_logo.attached? # returns FALSE !!!
Вывод на консоль:
[ActiveJob] Enqueued ActiveStorage::PurgeJob (Job ID: caebfa82-7c41-4eb9-b295-c213449e0a7e) to Async(active_storage_purge) with arguments: #<GlobalID:0x00007fcf6ae179e0 @uri=#<URI::GID gid://meta-shop/ActiveStorage::Blob/81>>
ActiveStorage::Blob Load (1.7ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", 81], ["LIMIT", 1]]
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] Performing ActiveStorage::PurgeJob (Job ID: caebfa82-7c41-4eb9-b295-c213449e0a7e) from Async(active_storage_purge) enqueued at 2021-09-25T10:01:32Z with arguments: #<GlobalID:0x00007fcf5a8856b8 @uri=#<URI::GID gid://meta-shop/ActiveStorage::Blob/81>>
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] TRANSACTION (2.0ms) BEGIN
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] ActiveStorage::Attachment Exists? (2.1ms) SELECT 1 AS one FROM "active_storage_attachments" WHERE "active_storage_attachments"."blob_id" = $1 LIMIT $2 [["blob_id", 81], ["LIMIT", 1]]
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] ActiveStorage::Attachment Load (2.8ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 81], ["record_type", "ActiveStorage::Blob"], ["name", "preview_image"], ["LIMIT", 1]]
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] ActiveStorage::Blob Destroy (8.8ms) DELETE FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 [["id", 81]]
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] TRANSACTION (5.1ms) COMMIT
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] S3 Storage (224.0ms) Deleted file from key: mx5g91bi8qwgvh6a8vzh65598kd3
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] S3 Storage (311.1ms) Deleted files by key prefix: variants/mx5g91bi8qwgvh6a8vzh65598kd3/
[ActiveJob] [ActiveStorage::PurgeJob] [caebfa82-7c41-4eb9-b295-c213449e0a7e] Performed ActiveStorage::PurgeJob (Job ID: caebfa82-7c41-4eb9-b295-c213449e0a7e) from Async(active_storage_purge) in 568.39ms
Как я могу сохранить User.shop.company_logo
при обновлении с nested_attributes
помощью ?
Комментарии:
1. Ну, вы обновили пользователя и дали новые параметры для магазина. Это было что-то вроде запроса на РАЗМЕЩЕНИЕ (а не ИСПРАВЛЕНИЯ), удаляющего вложение. Я чувствую, что это неправильный подход сам по себе. Рад, что кто-то предложил альтернативное решение.
2. Моя цель-не заменять Магазин, он должен только дополнять (или редактировать данные вложенные поля).
Ответ №1:
Я нашел решение:
Моя Shop
модель была заменена при обновлении через родительскую User
модель. Но есть опция, которую можно добавить в отношениях «один к одному», например has_one
. Это update_only
опция, которая false
установлена по умолчанию. При использовании этого вложенная модель обновляется и не заменяется при использовании update_only: false
accepts_nested_attributes_for :shop, update_only: true