我正在尝试使用Laravel Eloquent ORM在另一个连接上做一个简单的一对一关系。
让我们说:
MyModel::on('secondary_connection')->get()
这很好。
当我这样做时:
MyModel::on('secondary_connection')->with('AnotherModel')->get();
我收到错误,因为eloquent正在默认连接上执行AnotherModel SELECT语句(而不是“secondary_connection”)。
我无法找到解决这个问题的方法。
我的模型定义很好,因为我可以在默认连接中加入它们。
想法?
答案 0 :(得分:2)
好吧我被许多用户建议,似乎没有办法在飞行中这样做。我对此的理解是,在管理多连接时,Eloquent是不完整的。
有两种方法可以解决这个问题。
首先,在模型中指定连接:
class MyModel {
$protected connection = 'secondary_connection';
}
这显然是一个糟糕的解决方法,因为这个模型只能在一个连接中使用......但仍然有效。
然后,正如Jarek Tkaczyk建议的那样,可以用新的连接切换默认连接。但是,不是在配置文件中进行,而是可以交换PDO对象。
$default = DB::getPdo(); // Default conn
$secondary = DB::connection('secondary_connection')->getPdo();
DB::setPdo($secondary);
$result = MyModel::with('AnotherModel')->get();
DB::setPdo($default);
这是一种有效的解决方法,可以是一个干净的解决方案。下一步是将该切换机制放在一个很好的Laravel方式中。
答案 1 :(得分:0)
实际上没有办法实现它。
您需要更改默认连接才能使Eloquent将其用于预先加载的模型。你可以用这样的辅助方法包装它:
function on($connection, Closure $callback)
{
// backup default connection
$default = Config::get('database.default');
// change for current query
Config::set('database.default', $connection);
// run the query
$result = $callback();
// restore the default connection
Config::set('database.default', $default);
return $result;
}
然后就像下面这样打电话:
$models = on('secondary_connection', function () {
return MyModel::with('relation')->get();
});
答案 2 :(得分:0)
我最终用更多的自定义onces替换了简单的关系函数。例如,我的->relatedModel
有点像Eloquent模型中的原始副本,但包括设置连接:
public function relatedModel() {
$instance = new \relatedModel;
$instance->setConnection($this->getConnectionName());
$query = $instance->newQuery();
return new BelongsTo($query, $this, 'myForeignKey', $instance->getKeyName(), null);
}
我在Laravel 5上,所以这可能与4.2不同。
由于我现在正在摆弄这个问题,现在很多方法是通过另一个连接而不是默认的方式完成验证:http://laravel.io/forum/10-29-2014-validation-rules-and-multiple-db-connections
如果是模型方法,您甚至可以将其缩短为:
$v = Validator::make($data, $rules);
$v->getPresenceVerifier()->setConnection($this->getConnectionName());
答案 3 :(得分:0)
我也在处理这个问题。我找到了一个解决方案,但只有通过.env文件配置使用过的连接才可以使用它。如果你想动态地改变它,这将不起作用,尽管你可以在这种情况下使用一些逻辑(调用函数)来返回正确的连接名称。
我的解决方案是覆盖Model类的connectionName方法。在我的情况下,我有一个基类用于我的所有模型,负责这个:
abstract class ModelBase extends Model
{
public function getConnectionName()
{
return env('ELOQUENT_DB_CONNECTION', parent::getConnectionName());
}
}
正如我所提到的,你可以在getConnectionName中放置你想要的任何逻辑,这样你就可以使它更具动态性。
答案 4 :(得分:0)
class MyModel {
$protected connection = 'secondary_connection';
}
是一个不错的选择,因为雄辩的模型是DB Facades + Extras。所有DB Facades功能也适用于雄辩的模型。因此,除了在db Facade中更改连接之外,我们可以在此处更改它,只是没有区别。