Home > Net >  Laravel - How to pass variable to constructor to model and then use eloquent? dynamic set database c
Laravel - How to pass variable to constructor to model and then use eloquent? dynamic set database c

Time:02-24

I have an issue that I am struggling to resolve where I am trying to dynamically set the database connection when constructing the instance of the model. However I am struggling to use eloquent once I initialise the model.

In my model, I have the following constructor:

public function __construct(School $school, array $attributes = [])
{
    parent::__construct($attributes);

    if ($school instanceof School) {

        $host = $school->database;

        Config::set('database.connections.school', [
            'driver'   => 'mysql',
            'host'     => $host->host,
            'port'     => $host->port,
            'database' => $host->database_name,
            'username' => $host->database_username,
            'password' => $host->database_password,
        ]);

        $this->setConnection('school');

    }

}

Then in my controller I am trying to query the data like:

$student = new Student($this->selected_school);
$this->student = $student::query()->where('student_reference_code', $this->student_reference_code)->first();

However I am recieving the following error:

Too few arguments to function App\Models\Student::__construct(), 0 passed in /Users/user/Sites/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 1321 and at least 1 expected

I'm not sure whether this is the best way to set the database connection as each school will have seperate databases.

Any help on how I am able to use eloquent to query the model using the correct database connection by passing through the school would be much appreciated.

--

I have also tried to create a method within the model like:

public function getStudentByStudentReferenceCode($reference_code)
{
    return $this->where('student_reference_code', $this->student_reference_code)->first();
}


$this->student = $student->getStudentByStudentReferenceCode($this->student_reference_code);

However then I recieve the following:

App\Models\Student::__construct(): Argument #1 ($school) must be of type App\Models\School, array given, called in /Users/user/Sites/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 496

When dumping out what I am passing into new Student() constructor, and it is an instance of the school model?

CodePudding user response:

Overwriting the Eloquent model constructor is going to give you lots of trouble, don't do that. Laravel expects that it should be able to new static at anytime without issue, which it can't do if you added a required parameter to the constructor.

Instead, I recommend doing something like this in your model:

public static function connect(School $school)
{
    $host = $school->database;

    
    \Config::set('database.connections.school', [
        'driver'   => 'mysql',
        'host'     => $host->host,
        'port'     => $host->port,
        'database' => $host->database_name,
        'username' => $host->database_username,
        'password' => $host->database_password,
    ]);
    
    \DB::purge('school');

    return (new static)->setConnection('school');
}

Now use your own method when creating a new instance of your model, like this:

$student = Student::connect($this->selected_school)
    ->where('student_reference_code', $this->student_reference_code)
    ->first();
  • Related