$statement = $this->prepared($this->getPdoForSelect($useReadPdo)
->prepare($query));
vendor\laravel\framework\src\Illuminate\Database\Connection.php
Symfony \ Component \ Debug \ Exception \FatalThrowableError (E_ERROR)
Call to a member function prepare() on null
I'm having this same issue when trying to use the belongsTo relationship from a MongoDB model to a MySQL model.
The issue seems to be caused by the belongs to relationship trying to use the MongoDB connection. If I specify the connection property on the MySQL model to mysql then it works. This isn't a solution for me as in tests I use sqlite and in production I use mysql so I need it to use the default connection.
I'm using PHP 7.2, laravel v5.6.23, and laravel-mongodb v3.4.2
My mongodb model
use Jenssegers\Mongodb\Eloquent\Model;
class Notification extends Model
{
protected $connection = 'mongodb';
protected $collection = 'notifications';
public function tenant()
{
return $this->belongsTo('Tenant');
}
}
My MySQL model
use Illuminate\Database\Eloquent\Model;
use Jenssegers\Mongodb\Eloquent\HybridRelations;
class Tenant extends Model
{
use HybridRelations;
protected $table = 'tenants';
}
Stack trace of the error.
1) NotificationModelTest::it_belongs_to_a_tenant
Error: Call to a member function prepare() on null
/vendor/laravel/framework/src/Illuminate/Database/Connection.php:330
/vendor/laravel/framework/src/Illuminate/Database/Connection.php:661
/vendor/laravel/framework/src/Illuminate/Database/Connection.php:628
/vendor/laravel/framework/src/Illuminate/Database/Connection.php:337
/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1909
/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1894
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:481
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:465
/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php:77
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php:81
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:419
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:397
/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Eloquent/Model.php:145
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1414
I've done some more digging and when you hit the mysql relation from the mongodb model it tries to use the mongodb connection.
I've made a basic test using the models above. I'm just trying to hit the relation without any data which I would expect to return null.
$notification = new Notification();
$notification->tenant;
But that is throwing the following error.
1) NotificationModelTest::it_belongs_to_a_tenant
Error: Call to a member function prepare() on null
/vendor/laravel/framework/src/Illuminate/Database/Connection.php:330
/vendor/laravel/framework/src/Illuminate/Database/Connection.php:661
/vendor/laravel/framework/src/Illuminate/Database/Connection.php:628
/vendor/laravel/framework/src/Illuminate/Database/Connection.php:337
/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1909
/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1894
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:481
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:465
/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php:77
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php:81
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:419
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:397
/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Eloquent/Model.php:145
/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1414
When I run the test if I dd in the getConnectionName() method in Illuminate\Database\Eloquent\Model it returns 'mongodb', but it should return the default driver.
If I override that method in the Tenant model to return the default connection that fixes the issue.
use Illuminate\Database\Eloquent\Model;
use Jenssegers\Mongodb\Eloquent\HybridRelations;
class Tenant extends Model
{
use HybridRelations;
protected $table = 'tenants';
public function getConnectionName()
{
return config('database.default');
}
}
if you use native authentication in laravel with mongodb, you must change in the path
/vendor/laravel/framework/src/Illuminate/Foundation/Auth/User.php
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
#use Illuminate\Database\Eloquent\Model;
use Jenssegers\Mongodb\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\Authorizable;
class User extends Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}
@stardesign77, is it issue actual for you?
if you use native authentication in laravel with mongodb, you must change in the path
/vendor/laravel/framework/src/Illuminate/Foundation/Auth/User.php
<?php namespace Illuminate\Foundation\Auth; use Illuminate\Auth\Authenticatable; use Illuminate\Auth\MustVerifyEmail; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; #use Illuminate\Database\Eloquent\Model; use Jenssegers\Mongodb\Eloquent\Model; use Illuminate\Foundation\Auth\Access\Authorizable; class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract { use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail; }
not worked for Laravel 8.x