Включить активные вложения хранилища в запрос активной записи

#ruby-on-rails #activerecord #rails-activestorage

#ruby-on-rails #activerecord #rails-activestorage

Вопрос:

Используя Rails 5.2 и Active Storage, я создал Item класс с некоторыми images :

 class Item < ApplicationRecord
  has_many_attached :images
end
  

Я бы хотел использовать ActiveRecord::QueryMethods.includes для быстрой загрузки images довольно стандартный материал Rails с has_many , но:

 Item.includes(:images)
=> ActiveRecord::AssociationNotFoundError ("Association named 'images' was not found on Item; perhaps you misspelled it?")

Item.includes(:attachments)
=> ActiveRecord::AssociationNotFoundError ("Association named 'attachments' was not found on Item; perhaps you misspelled it?")

Item.includes(:active_storage_attachments)
=> ActiveRecord::AssociationNotFoundError ("Association named 'active_storage_attachments' was not found on Item; perhaps you misspelled it?")
  

Есть идеи, как заставить это работать?

Ответ №1:

ActiveStorage предоставляет метод для предотвращения N 1 запросов

 Gallery.where(user: Current.user).with_attached_photos
  

https://api.rubyonrails.org/classes/ActiveStorage/Attached/Model.html#method-i-has_many_attached

Итак, в вашем случае:

 Item.with_attached_images
  

Комментарии:

1. Это сработало. Но предоставленная вами ссылка не работает api.rubyonrails.org/v5.2/classes/ActiveStorage/Attached /…

Ответ №2:

…aa и я нашел ответ:

 Item.reflections.keys
=> ["location", "images_attachments", "images_blobs", "taggings", "base_tags", "tag_taggings", "tags"]
  

Имя ассоциации, сгенерированной активным хранилищем, является, images_attachments даже если оно доступно через Item#images . Вот решение:

 Item.includes(:images_attachments)
  Item Load (0.6ms)  SELECT  "items".* FROM "items" LIMIT $1  [["LIMIT", 11]]
  ActiveStorage::Attachment Load (0.6ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" IN ($3, $4, $5, $6, $7)  [["record_type", "Item"], ["name", "images"], ["record_id", 3], ["record_id", 2], ["record_id", 4], ["record_id", 5], ["record_id", 1]]
=> #<ActiveRecord::Relation […]>