Repository: DirectoryTree/LdapRecord (PHP)

Issue:
[Bug] Groups relation Builder TypeError
**Environment:**
 - LDAP Server Type: ActiveDirectory
 - PHP Version: 8.2

**Describe the bug:**
Hi! I am having a curious problem. After upgrading to Ldap Record v3, the query below gives me an error:

`LdapRecord\Query\Model\Builder::newInstance(): Return value must be of type LdapRecord\Query\Model\ActiveDirectoryBuilder, LdapRecord\Query\Model\Builder returned`

on the `whereIn()` - meaning the `groups()` relation resolves into wrong Builder?

```
$roles = LdapRecord\Models\ActiveDirectory\User::where('cn', '=', 'MYNAME')
    ->first()
    ->groups()
    ->whereIn('cn', ['LIST', 'OF', 'GROUPS'])
    ->get();
```

I'm a little lost now. Could you help? Is this a bug? Thanks in advance.


Discussion:
Hi @misakstvanu,

I'm able to reproduce this thanks! Fixing now 🙏 
Lovely! Thank you!
Ok this [has been patched](https://github.com/DirectoryTree/LdapRecord/releases/tag/v3.2.2)! Please run `composer update` and you should be all set 👍 



Patch:
diff --git a/src/Query/Builder.php b/src/Query/Builder.php
index 1740c26a..1dfe8c31 100644
--- a/src/Query/Builder.php
+++ b/src/Query/Builder.php
@@ -156,7 +156,7 @@ public function setCache(Cache $cache = null): static
     /**
      * Returns a new Query Builder instance.
      */
-    public function newInstance(string $baseDn = null): static
+    public function newInstance(string $baseDn = null): Builder
     {
         return (new static($this->connection))->setDn(
             is_null($baseDn) ? $this->getDn() : $baseDn
@@ -166,7 +166,7 @@ public function newInstance(string $baseDn = null): static
     /**
      * Returns a new nested Query Builder instance.
      */
-    public function newNestedInstance(Closure $closure = null): static
+    public function newNestedInstance(Closure $closure = null): Builder
     {
         $query = $this->newInstance()->nested();
 
@@ -1026,7 +1026,7 @@ public function whereNotContains(string $field, string $value): static
      */
     public function whereIn(string $field, array $values): static
     {
-        return $this->orFilter(function (self $query) use ($field, $values) {
+        return $this->orFilter(function (Builder $query) use ($field, $values) {
             foreach ($values as $value) {
                 $query->whereEquals($field, $value);
             }
diff --git a/src/Query/Model/Builder.php b/src/Query/Model/Builder.php
index f97c915a..7c694730 100644
--- a/src/Query/Model/Builder.php
+++ b/src/Query/Model/Builder.php
@@ -91,7 +91,7 @@ public function getModel(): Model
     /**
      * Get a new model query builder instance.
      */
-    public function newInstance(string $baseDn = null): static
+    public function newInstance(string $baseDn = null): BaseBuilder
     {
         return parent::newInstance($baseDn)->model($this->model);
     }
@@ -236,7 +236,7 @@ public function findManyByAnr(array $values = [], array|string $columns = ['*'])
      */
     protected function prepareAnrEquivalentQuery(string $value): static
     {
-        return $this->orFilter(function (self $query) use ($value) {
+        return $this->orFilter(function (BaseBuilder $query) use ($value) {
             foreach ($this->model->getAnrAttributes() as $attribute) {
                 $query->whereEquals($attribute, $value);
             }


Test patch:
diff --git a/tests/Unit/Models/ActiveDirectory/ModelTest.php b/tests/Unit/Models/ActiveDirectory/ModelTest.php
index bea7f406..56d1c17a 100644
--- a/tests/Unit/Models/ActiveDirectory/ModelTest.php
+++ b/tests/Unit/Models/ActiveDirectory/ModelTest.php
@@ -2,7 +2,11 @@
 
 namespace LdapRecord\Tests\Unit\Models\ActiveDirectory;
 
+use LdapRecord\Connection;
+use LdapRecord\Container;
 use LdapRecord\Models\ActiveDirectory\Entry;
+use LdapRecord\Models\Relations\HasMany;
+use LdapRecord\Query\Model\ActiveDirectoryBuilder;
 use LdapRecord\Query\Model\Builder;
 use LdapRecord\Tests\TestCase;
 use Mockery as m;
@@ -88,6 +92,26 @@ public function test_restore()
 
         $this->assertEquals('CN=John Doe,DC=local,DC=com', $m->getDn());
     }
+
+    public function test_relation_query_can_be_created()
+    {
+        Container::addConnection(new Connection);
+
+        $entry = new class extends Entry
+        {
+            public function relation(): HasMany
+            {
+                return $this->hasMany(Entry::class, 'dn');
+            }
+        };
+
+        /** @var HasMany $relation */
+        $relation = $entry->relation()->whereIn('foo', ['foo']);
+
+        $this->assertInstanceOf(HasMany::class, $relation);
+        $this->assertInstanceOf(ActiveDirectoryBuilder::class, $query = $relation->getQuery());
+        $this->assertEquals('(|(foo=\66\6f\6f))', $query->getQuery());
+    }
 }
 
 class TestModelRestoreStub extends Entry