framework: [Eloquent] Relations doesn't use connection of parent model.
I try to get models with their relation from connection, which is chosen dynamically:
User::on('another-db')->with('article')->get();
Unfortunately, instance of related model, which is created in the Model::hasMany()
function does not contain this connection.
Solution is to modify function as follows:
public function hasMany($related, $foreignKey = null, $localKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related;
// FIX
if ($instance->getConnection() == null) {
$instance->setConnection($this->connection);
}
$localKey = $localKey ?: $this->getKeyName();
return new HasMany($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
}
This solution may be used also in belongsTo()
, belongsToMany()
, etc.
I can create the pull request, but I think this solution may be undesirable if the user wants to define the relation between the parent model from another-db connection and the related model from default connection. This solution override a default connection in related model.
However, I believe that relations between models from the same database are more likely than relations between models from different databases.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 1
- Comments: 30 (9 by maintainers)
Why is it closed without a solution? Model relationships aren’t inheriting parent’s connections, we aren’t able to set a connection for them neither
For those who still has this problem:
I hope it helps!
This is already implemented on L5.4, although I think it should be optional by setting something like
protected $inheritConnection = true;
because its annoying to handle some times.Or better yet, I like reno1979’s idea of
App\myModel::on('mysql2', true); /* True for propegate connection */
Currently every model sets its own connection and there’s no way to force the parent connection, I’m checking with Taylor if adding such functionality would be a good idea.
I did a completely unorthodox way, I needed an extremely urgent fix, and since this hasn’t been updated for 2 years I just added this line in the Model.php on all the relationship functions:
And it just works as expected absolutely everywhere, if there is no connection overload, it just uses the default one and that’s it.
I think it should be the official fix, but until then I had to commit the Laravel framework folder to my repository, and lock the version in composer.
I hope an official fix will soon arise so I don’t have to do these kinds of blasphemy.
Sorry to revive a crazy old issue but this still happens in laravel 5.8-7.x.
I’ve found a possible solution which involves overwriting
Illuminate/Database/Eloquent/Concerns/HasRelationships.php
newRelatedInstance()
method. This can be done in your base model and seems fairly easy. https://github.com/laravel/ideas/issues/2326@avasa I didn’t read everything yet, but do you use the most recent laravel version? Much things are already fixed…
@GrahamCampbell @taylorotwell @themsaid @BartHuis
Could this issue please be reopend? I’ve encounter multiple issues this week, all caused by this underlying mecanism/issue.
I ‘solved’ it with changing the default database connection and restoring it, but this is going to introduce unwanted effects eventually.
Adding this ‘fix’ to relations in a own made model should work:
When a Laravel extension (which creates relations in your Models etc) is used, this extension should also apply this ‘fix’. 😦
But a real solution would be much nicer. I saw a proposal for a propegateConnection by @davisonja Something like that could work. Or similar:
I also encountered this issue in 5.3.19 😦
I hope there will be a real fix for this