让我们想象一下具有两个具有HABTM关联的资源(用户和书籍)的Ruby模式。
当我基于这种关联进行过滤时,无论用户是否有一本书,Ruby的行为都会有些奇怪:
2.5.3 :007 > Contact.includes(:books).count
(4.7ms) SELECT COUNT(*) FROM "contacts"
=> 36880
这很好,因为它返回与任何图书关联的联系人的总价值。
2.5.3 :010 > Contact.includes(:books).where(books: {"id":[1,2] }).count
(34.0ms) SELECT COUNT(DISTINCT "contacts"."id") FROM "contacts" LEFT OUTER JOIN "contacts_books" ON "contacts_books"."contact_id" = "contacts"."id" LEFT OUTER JOIN "books" ON "books"."id" = "contacts_books"."book_id" WHERE "books"."id" IN (?, ?) [["id", 1], ["id", 2]]
=> 24864
这还可以,因为它返回ID为1或2的所有联系人。
2.5.3 :011 > Contact.includes(:books).where.not(books: {"id":[1,2] }).count
(13.0ms) SELECT COUNT(DISTINCT "contacts"."id") FROM "contacts" LEFT OUTER JOIN "contacts_books" ON "contacts_books"."contact_id" = "contacts"."id" LEFT OUTER JOIN "books" ON "books"."id" = "contacts_books"."book_id" WHERE "books"."id" NOT IN (?, ?) [["id", 1], ["id", 2]]
=> 0
现在这部分没有意义,因为它应该是总数-#associations,所以36880-24864给我留下了12016条记录,而不是0。
或者我想念什么?
Rails 5.2.2 红宝石2.5.3p105(2018-10-18修订版65156)[x86_64-darwin17]
答案 0 :(得分:0)
where条件将要求加载的联系人至少有一本书,例如如果没有书号,则无法检查书号是否在数组中。
我如何调试的:
当我尝试重现您的问题时,我有一个小仓库:
$client = new SoapClient("https://etrack.postaplus.net/APIService/PostaWebClient.svc?singleWsdl", array("trace" => 1, "exception" => 0));
$params = array(
"CodeStation" => `BEY`,
"PickupNumber" => `1`,
"Reason" => `test reason`,
"Password" => `sss`,
"ShipperAccount" => `acc`,
"UserName" => `acc`,
);
$client->Pickup_Cancel($params);
最小复制回购:https://github.com/localhostdotdev/bug/tree/has-and-belongs-to-many-includes-count