Ruby HATBM-负过滤行为很奇怪

时间:2019-05-06 11:53:18

标签: sql ruby-on-rails has-and-belongs-to-many

让我们想象一下具有两个具有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]

1 个答案:

答案 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