对活动模型序列化程序属性的嵌套查询
nested query on active model serializer attribute
我有两个模型,艺术品和事件,一个艺术品有很多事件。
部分活动已确认。
在我的序列化程序中,我想return每个艺术品的最后确认事件
现在它可以,但也会创建一个缓慢的(n+1?)查询,其中每个序列化的艺术品都会获取所有事件。
我怎样才能做得更快?
# artwork_controller.rb
def index
@artworks = Artwork.all
render json: @artworks
end
# artwork_serializer.rb
attributes :id, :name, :photo, :created_at
has_one :event do
object.events.confirmed.last
end
和日志
Processing by Api::V1::ArtworksController#index as JSON
Passenger Load (2.0ms) SELECT "artworks".* FROM "artworks"
↳ app/controllers/api/v1/artworks_controller.rb:11
[active_model_serializers] Event Load (1.2ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 16], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] Event Load (0.8ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 9], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] Event Load (2.1ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 27], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9#
# ... for each artwork
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] User Load (1.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 84], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/event_serializer.rb:9
[active_model_serializers] CACHE Event Load (0.0ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 9], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 88], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/event_serializer.rb:9
[active_model_serializers] CACHE Event Load (0.0ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 27], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 76], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/event_serializer.rb:9
[active_model_serializers] CACHE Event Load (0.0ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 11], ["published", true], ["LIMIT", 1]]
# ... for each artwork events
你可以试试这个:
请将此关联添加到 artwork
模型。
# app/models/artwork.rb
has_one :last_confirmed_event, -> { order(created_at: :desc).where(confirmed: true) }, class_name: "Event"
在您的 artworks
控制器中添加 eager-loading。
# app/controllers/artwork_controllers.rb
def index
@artworks = Artwork.all.includes(:last_confirmed_event)
render json: @artworks
end
最后一次在你的序列化程序中使用声明的关联。
# app/serializers/artwork_serializer.rb
attributes :id, :name, :photo, :created_at
has_one :last_confirmed_event
您可以根据自己的选择更改关联名称。
我有两个模型,艺术品和事件,一个艺术品有很多事件。 部分活动已确认。
在我的序列化程序中,我想return每个艺术品的最后确认事件
现在它可以,但也会创建一个缓慢的(n+1?)查询,其中每个序列化的艺术品都会获取所有事件。
我怎样才能做得更快?
# artwork_controller.rb
def index
@artworks = Artwork.all
render json: @artworks
end
# artwork_serializer.rb
attributes :id, :name, :photo, :created_at
has_one :event do
object.events.confirmed.last
end
和日志
Processing by Api::V1::ArtworksController#index as JSON
Passenger Load (2.0ms) SELECT "artworks".* FROM "artworks"
↳ app/controllers/api/v1/artworks_controller.rb:11
[active_model_serializers] Event Load (1.2ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 16], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] Event Load (0.8ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 9], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] Event Load (2.1ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 27], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9#
# ... for each artwork
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] User Load (1.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 84], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/event_serializer.rb:9
[active_model_serializers] CACHE Event Load (0.0ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 9], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 88], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/event_serializer.rb:9
[active_model_serializers] CACHE Event Load (0.0ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 27], ["published", true], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/artwork_serializer.rb:9
[active_model_serializers] User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 76], ["LIMIT", 1]]
[active_model_serializers] ↳ app/serializers/api/v1/event_serializer.rb:9
[active_model_serializers] CACHE Event Load (0.0ms) SELECT "events".* FROM "events" WHERE "events"."artwork_id" = AND "events"."published" = ORDER BY "events"."created_at" DESC LIMIT [["artwork_id", 11], ["published", true], ["LIMIT", 1]]
# ... for each artwork events
你可以试试这个:
请将此关联添加到 artwork
模型。
# app/models/artwork.rb
has_one :last_confirmed_event, -> { order(created_at: :desc).where(confirmed: true) }, class_name: "Event"
在您的 artworks
控制器中添加 eager-loading。
# app/controllers/artwork_controllers.rb
def index
@artworks = Artwork.all.includes(:last_confirmed_event)
render json: @artworks
end
最后一次在你的序列化程序中使用声明的关联。
# app/serializers/artwork_serializer.rb
attributes :id, :name, :photo, :created_at
has_one :last_confirmed_event
您可以根据自己的选择更改关联名称。