【问题标题】:How to eager_load attachments: 1+N problem not working with ActiveStorage attachments如何 eager_load 附件:1+N 问题不适用于 ActiveStorage 附件
【发布时间】:2021-05-09 20:30:07
【问题描述】:

我有一个针对 JSON API 响应进行序列化的产品列表

为此,我还需要来自 ActiveStorage 附件的 imageUrl。 我偶然发现了 1+N 的问题。

如您所见,我已经尝试包含任何类型的“includes” 我已经添加了'with_attached_photos'

如何解决这个 1+N 问题?

model:

class Product
  ActiveStorage::Current.host = ENV['APPLICATION_URL']
  include Rails.application.routes.url_helpers

  has_many_attached :photos
  has_and_belongs_to :categories

  def photo_thumbnail_urls
    photos.map do |photo|
      # this generates urls for the API
      rails_representation_url(photo.variant(thumb_options), host: ActiveStorage::Current.host)
    end
  end
end

这是我的controller

类 ProductsController

  # as you can see, I already tried to include any kind of 'includes' 
  # and I already added the 'with_attached_photos' 

  top_rated_products = Product.includes(:categories,
                                        :active_storage_blobs,
                                        :categories_products,
                                        :active_storage_attachments,
                                        photos_attachments: :blob,
    where("lower(name) LIKE lower(?)", "%" + query_param + "%").
    where("categories_products.category_id": [1,2,3,4]).
    with_attached_photos

  render json: top_rated_products, each_serializer: TopProductSerializer

结束

这是我的Serializer

class TopProductSerializer < ActiveModel::Serializer
  attribute :id
  attribute :name
  attribute :photo_thumbnail_urls, key: :images
end

但我的控制台充满了这样的查询:

 Product Load (4.2ms)  SELECT "products".* FROM "products" WHERE (lower(name) LIKE lower('%ha%')) ORDER BY created_at asc LIMIT $1  [["LIMIT", 5]]
  ↳ app/controllers/products_controller.rb:116:in `top_rated'
  HABTM_Categories Load (0.3ms)  SELECT "categories_products".* FROM "categories_products" WHERE "categories_products"."product_id" IN ($1, $2, $3, $4, $5)  [[nil, 740], [nil, 741], [nil, 742], [nil, 744], [nil, 746]]
  ↳ app/controllers/products_controller.rb:116:in `top_rated'
  Category Load (0.2ms)  SELECT "categories".* FROM "categories" WHERE "categories"."id" IN ($1, $2)  [[nil, 100], [nil, 5107]]
  ↳ app/controllers/products_controller.rb:116:in `top_rated'
[active_model_serializers]   ActiveStorage::Attachment Load (0.2ms)  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  [["record_id", 740], ["record_type", "Product"], ["name", "photos"]]
[active_model_serializers]   ↳ app/models/product.rb:53:in `photo_thumbnail_urls'
[active_model_serializers]   ActiveStorage::Blob Load (0.1ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 3840], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/models/product.rb:55:in `block in photo_thumbnail_urls'
[active_model_serializers]   ActiveStorage::Blob Load (0.2ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 3841], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/models/product.rb:55:in `block in photo_thumbnail_urls'
[active_model_serializers]   ActiveStorage::Blob Load (0.1ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 3842], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/models/product.rb:55:in `block in photo_thumbnail_urls'
[active_model_serializers]   ActiveStorage::Blob Load (0.1ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 3843], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/models/product.rb:55:in `block in photo_thumbnail_urls'
[active_model_serializers]   ActiveStorage::Blob Load (0.2ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 3844], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/models/product.rb:55:in `block in photo_thumbnail_urls'
# and so on and so on... 
#......
#....
#...
#..
#.

我还错过了什么?

【问题讨论】:

    标签: activerecord ruby-on-rails-6 has-and-belongs-to-many rails-activestorage


    【解决方案1】:

    我得到了它的工作:

    class Product
      scope :eager_load_photos, -> { includes photos_attachments: :blob }
    end
    
    Product.eager_load_photos.where(......).limit(n) # and so on
    

    1+N 的问题已经完全解决了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-30
      • 1970-01-01
      • 2018-06-17
      • 1970-01-01
      • 2019-01-18
      • 2020-03-01
      • 1970-01-01
      • 2020-02-07
      相关资源
      最近更新 更多