这又是一个后续问题:
Multi tenancy in Laravel Eloquent ORM
这一次,我有一些问题需要在多租户环境中使用关系来构建雄辩的模型。
给定一个产品模型:
class Product extends Eloquent {
public function accessories()
{
return $this->belongsToMany('Accessory', 'product_accessory', 'product_id', 'accessory_id')
->withPivot('id')
->withTimestamps();
}
这是确保relationship方法accessories()使用正确数据库连接的简单方法吗?现在,当我执行这样的附加方法时:
$product->accessories()->attach($accessory->id, $attributes);
Accessories方法似乎指向另一个不同于$product实体的数据库。我认为这是因为当关系被实例化时,附件模型连接不会被更改。
最佳答案
如果你看到我对你最初关于模型事件和观察者的问题的回答,这也应该能从本质上解决这个问题:Multi tenancy in Laravel Eloquent ORM
所有雄辩的关系方法:附加,关联等。所有这些都会触发此处详述的相应模型事件:http://laravel.com/docs/5.0/eloquent#model-events
如果您设置了一个模型观察器来在特定模型的保存前和保存后操作连接,那么您的所有关系调用都将自动相应地设置数据库连接。
希望这有帮助
--根据评论编辑
你好,尤伦,
对不起,我把你的配件电话错当成了同事。(保存关系)
但是,在定义关系时,您应该能够获得类似的结果。请参见以下示例:
class ProductModel extends Eloquent {
protected $table = 'products';
protected $connection;
protected $databases = [
'default' => 'mysql-key1',
'products' => 'mysql-key2'
];
public function __construct(Connection $connection)
{
$this->connection = $connection;
}
public function accessories()
{
$this->connection->reconnect($this->databases['products']);
$accessories = $this->hasMany('AccessoriesModel');
$this->connection->reconnect($this->databases['default']);
return $accessories;
}
}
然后,您可以进一步创建一个抽象类,所有受影响的模型都可以扩展该类,例如:
abstract class DatabaseModel extends Eloquent {
protected $connection;
protected $databases = [
'default' => 'mysql-key1',
'products' => 'mysql-key2'
];
public function __construct(Connection $connection)
{
$this->connection = $connection;
}
protected function setProductsDatabase()
{
$this->connection->reconnect($this->databases['products']);
}
protected function resetDatabaseConnection()
{
$this->connection->reconnect($this->databases['default']);
}
}
class ProductModel extends DatabaseModel {
protected $table = 'products';
public function accessories()
{
$this->setProductsDatabase();
$accessories = $this->hasMany('AccessoriesModel');
$this->resetDatabaseConnection();
return $accessories;
}
}
这样,只要关系配置正确,一切都将“自然”地运行,而不需要任何额外的代码。
一个更简洁,但更复杂的解决方案是,不要在模型中操纵数据库,您可以触发自己的“retrieving”事件,然后可以向模型观察者添加一个事件处理程序,用于自定义的“retrieving”事件-这将是我的首选,您可以在这里找到有关如何执行此操作的更多信息:http://laravel.io/forum/05-24-2014-how-could-i-create-custom-model-events?page=1
希望这有帮助