活动模型序列化器对象不返回所有关联记录(有很多:通过关系)

Active Model Serializer object not returning all association records (has many: through relationship)

所以我有 User&Role 模型,它使用 has_many 链接到 UserRole 模型:通过关联。我正在为用户使用序列化程序。注意:用户有很多角色。但由于某种原因,我无法获得序列化程序中的所有角色。这是查询,

unless params['roles'].blank?
  render json: User.includes(:roles)
                    .references(:user_roles)
                    .where('roles.name IN (?)', params['roles'])
else
  render json: User.all
end

在我的用户序列化器中我有

attributes :id, :name, :email, :roles

def roles
  object.roles.pluck(:name)
end

这件事是,我有一个同时具有 "admin"、"author" 角色的用户。当我将 "admin" 作为参数传递时,输出 json 对象只有该用户的 roles: ["admin"]。调试后,对于此对象,object.roles.count 为 2,但当我执行 object.roles 时,它仅显示 1 条记录。发生什么事了?

当我执行 User.find(object.id).roles.pluck(:name) 时,这有效。但这会在序列化程序循环中运行查询..

对于 User.all 没有 OUT 参数的输出响应非常好。 (获取角色:["author"、"admin"])。问题是当我传递一个参数时。也许我的查询有问题?

由于 where 子句限制了加载的记录,您可能需要使用子查询:

User.includes(:roles).where(
  id: User.joins(:roles).where(roles: { name: params[:roles] })
)

如果您查看生成的 SQL,您会发现此处的 where 子句仅适用于子查询 - 因此所有关联的角色都被加载,而不仅仅是匹配 WHERE "roles"."name" = 的角色。

  User Load (3.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" IN (SELECT "users"."id" FROM "users" INNER JOIN "user_roles" ON "user_roles"."user_id" = "users"."id" INNER JOIN "roles" ON "roles"."id" = "user_roles"."role_id" WHERE "roles"."name" IN (, , )) LIMIT   [["name", "admin"], ["name", "foo"], ["name", "bar"], ["LIMIT", 11]]
  UserRole Load (0.6ms)  SELECT "user_roles".* FROM "user_roles" WHERE "user_roles"."user_id" =   [["user_id", 1]]
  Role Load (0.5ms)  SELECT "roles".* FROM "roles" WHERE "roles"."id" =   [["id", 1]]

此外,如果您想使用已加载的记录,您需要使用 map 而不是 pluck,因为 pluck 的设计会创建一个单独的 select 查询。

def roles
  object.roles.map(&:name)
end