Search code examples
ruby-on-railsrubyember.jsember-dataactive-model-serializers

ActiveModel Serializer sending all records instead of specified limited amount


I have a controller that looks like this:

class MetricsController < ApplicationController
  def index
    org = current_user.organization
    metrics = Metric.where(organization: org).last(100)
    render json: metrics, status: 200, include: [:organization]
  end
end

metrics model:

class Metric < ActiveRecord::Base
  belongs_to :organization
end

organization:

class Organization < ActiveRecord::Base
  has_many :metrics
end

MetricSerializer:

class MetricSerializer < ActiveModel::Serializer
  embed :ids
  attributes :id, :provisioned_users, :connected_users, :created_at

  has_one :organization

end

OrganizationSerializer:

class OrganizationSerializer < ActiveModel::Serializer
  attributes :id, :name, :org_id, :gauth_enabled

  has_many :metrics
end

the JSON though that gets returned

organizations: [
  {
    id: 1,
    name: "ACME",
    org_id: "org_id232323",
    gauth_enabled: "f",
    metric_ids: [
      1,
      2,
      3,
      ...
      1000
    ]
  }
],

As you can see my serializer is spitting out every record in the Metric's table when I presumably only want the last 100. I'm unsure what I've set up wrong in AMS (0.8).

Interestingly my rails console shows the right SQL with the correct limits:

Metric Load (0.7ms)  SELECT  "metrics".* FROM "metrics"   ORDER BY "metrics"."id" DESC LIMIT 100
  Organization Load (0.3ms)  SELECT  "organizations".* FROM "organizations"  WHERE "organizations"."id" = $1 LIMIT 1  [["id", 1]]

Solution

  • Check out the guides on associations:

    By default, serializers simply look up the association on the original object. You can customize this behavior by implementing a method with the name of the association and returning a different Array.

    So, each model gets serialized according to its serializer. Your organization models were being put through your OrganizationSerializer, which had has_many :metrics specified. Thus, rails looked up all of the metrics for that organization, and serialized them.

    You didn't want that, you just cared about the one organization which the metric belonged to. So simply remove that line, and rails won't serialize the rest.