我已经在几个地方看到"远离"这个,但唉 - 这就是我的数据库的构建方式:
class Album extends Eloquent {
// default connection
public function genre() {
return $this->belongsTo('genre');
}
Run Code Online (Sandbox Code Playgroud)
和流派表:
class Genre extends Eloquent {
protected $connection = 'Resources';
}
Run Code Online (Sandbox Code Playgroud)
我的database.php:
'Resources' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'resources',
'username' => 'user',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'my_data',
'username' => 'user',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
Run Code Online (Sandbox Code Playgroud)
当我试图跑
Album::whereHas('genre', function ($q) {
$q->where('genre', 'German HopScotch');
});
Run Code Online (Sandbox Code Playgroud)
它没有正确选择(不会将数据库名称添加到表"genres"):
Next exception 'Illuminate\Database\QueryException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'my_data.genres' doesn't exist
Run Code Online (Sandbox Code Playgroud)
重要的是要注意这是完美的:
Album::first()->genre;
Run Code Online (Sandbox Code Playgroud)
更新
到目前为止,我发现的最好的方法是使用构建器的"from"方法来专门命名正确的连接.我发现查询中的构建器可以接收"from"
Album::whereHas('genre', function ($q) {
$q->from('resources.genres')->where('genre', 'German HopScotch');
});
Run Code Online (Sandbox Code Playgroud)
这是一个不错的解决方案,但它需要我挖掘数据库php并找到一个很好的方法从关系'genre'获取正确的表和数据库名称.
如果有其他人可以在这个解决方案的基础上进一步发展,我会很感激.
Sab*_*osh 24
laravel v5.7及以上解决方案
class Album extends Eloquent {
// default connection
public function genre() {
return $this->setConnection('Resources')->belongsTo('genre');
}
...
}
Run Code Online (Sandbox Code Playgroud)
这是我自己的解决方案,它对我来说一般都适用,但它很复杂.
我正在使用构建器"from"方法在子查询中正确设置表和数据库.我只需要在里面传递正确的信息.
假设子查询可以像"genres.sample"一样复杂甚至更深(这意味着专辑与流派有关系,并且流派与样本有关系)这是如何
$subQuery = 'genres.samples';
$goDeep = (with (new Album));
$tableBreakdown = preg_split('/\./', $subQuery); // = ['genres', 'samples']
// I recurse to find the innermost table $album->genres()->getRelated()->sample()->getRelated()
foreach ($tableBreakdown as $table)
$goDeep = $goDeep->$table()->getRelated();
// now I have the innermost, get table name and database name
$alternativeConnection = Config::get("database.connections." . $goDeep->getConnectionName() . ".database"); // should be equal to the correct database name
$tableName = $goDeep->getTable(); // I have to use the table name in the "from" method below
Album::whereHas($subQuery, function ($q) use ($alternativeConnection, $tableName) {
$q->from("$alternativeConnection.$tableName");
$q->where(....... yadda yadda);
});
Run Code Online (Sandbox Code Playgroud)
TL:博士;
Album::whereHas('genres', function ($q) {
$q->from('resources.genres')->where(....);
});
Run Code Online (Sandbox Code Playgroud)
这是它对我有用的方式:
在我的 .env 和 config/database.php 中,我定义了我的其他连接 =>如何在 Laravel 中使用多个数据库
我以这种方式更新了我的模型:
class MyOtherDBModel extends Model
{
protected $table = 'tablename';
protected $connection = 'mysql2';
public function __construct(array $attributes = [])
{
$this->table = env('DB_DATABASE_2').'.'.$this->table;
parent::__construct();
}
}
class MyModel extends Model
{
public function myOtherModel()
{
return $this->belongsTo(MyOtherDBModel::class, 'field', 'field');
}
}
Run Code Online (Sandbox Code Playgroud)
现在我可以打电话
$query = MyModel::whereHas('myOtherModel');
Run Code Online (Sandbox Code Playgroud)
看起来Eager Loading会做你想做的事
Album::with(['genre' => function ($q) {
$q->connection('Resources')
->where('genre', 'German HopScotch');
}]);
Run Code Online (Sandbox Code Playgroud)
在流派模型上添加具有默认连接的连接变量:
protected $connection = 'mysql';
Run Code Online (Sandbox Code Playgroud)
由于没有添加这个,我的关系出现了一些问题。
以防万一有人到达这里。
当您使用来自不同数据库连接的关系获取数据时,请确保相关表已$connection定义该属性,即使它是默认连接也是如此。
Account模型:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Account extends Model {
protected $connection = 'different_connection';
public function verifiedBy()
{
return $this->belongsTo(User::class, 'verified_by');
}
}
Run Code Online (Sandbox Code Playgroud)
User模型:
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable {
// this one uses the default - `database.default` connection
public function approved()
{
return $this->hasMany(Account::class, 'verified_by');
}
}
Run Code Online (Sandbox Code Playgroud)
一旦我这样做Account:find($id)->verifiedBy,它就会抛出错误。查看数据库名称就可以发现。但如果您这样做,User::find($id)->approved它将正常工作,因为Account模型已定义连接。反之则不然。
因此,为了安全起见,如果您处理多个数据库连接,请将$connection属性放入模型中。
Laravel 的实现
您应该先克隆,否则您将更改模型的默认连接。它会产生副作用。
class Album extends Eloquent {
public function genre() {
$newResource = clone $this;
return $newResource->setConnection('Resources')->belongsTo('genre');
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10232 次 |
| 最近记录: |