Active Model Serializer对象未返回所有关联记录(有很多:通过关系)

时间:2019-01-10 13:11:39

标签: ruby-on-rails relationship has-many-through active-model-serializers

所以我有User&Role模型,它使用has_many:through关联链接到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”作为参数传递时,Output json对象仅对该用户具有roles: ["admin"]。调试后,对于该对象,当我执行object.roles.countobject.roles是2 BUT,它仅显示1条记录。发生什么事了?

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

对于带OUT参数的User.all,输出响应非常好。 (获得角色:[“作者”,“管理员”])。问题是当我通过参数时。也许我的查询有问题?

1 个答案:

答案 0 :(得分:1)

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

def arp_ping():
    ans, unans = srp(Ether(src = "b8:27:eb:a0:57:ff", dst="ff:ff:ff:ff:ff:ff:ff:ff")/ARP(pdst="172.16.16.0/24"),timeout=2)
    print(ans.summary(lambda p: p[1].sprintf("%Ether.src% is at %ARP.psrc%")))
    print(ARP.psrc)
    if ans.summary(lambda p: p[1].sprintf("%ARP.psrc%")) == "172.16.16.206":
        print(ans.summary(lambda p: p[1].sprintf("blueberry is %Ether.src% at %ARP.psrc%")))

如果查看生成的SQL,您会发现这里的where子句仅适用于子查询-因此,所有关联的角色都已加载,而不仅仅是与User.includes(:roles).where( id: User.joins(:roles).where(roles: { name: params[:roles] }) ) 匹配的角色。

WHERE "roles"."name" = $1

此外,如果要使用加载的记录,则需要使用 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 ($1, $2, $3)) LIMIT $4 [["name", "admin"], ["name", "foo"], ["name", "bar"], ["LIMIT", 11]] UserRole Load (0.6ms) SELECT "user_roles".* FROM "user_roles" WHERE "user_roles"."user_id" = $1 [["user_id", 1]] Role Load (0.5ms) SELECT "roles".* FROM "roles" WHERE "roles"."id" = $1 [["id", 1]] 而不是map,这是设计使然,它会创建一个单独的选择查询。

pluck