Laravel Eloquent ORM 中的多租户
这是来自
强制 Eloquent 模型重新解析数据库连接
有多个数据库连接:
return [
'default' => 'mysql-key1',
'connections' => [
'mysql-key1' => [
'driver' => 'mysql',
'database' => 'key1_dbname,
// etc
],
'mysql-key2' => [
'driver' => 'mysql',
'database' => 'key2_dbname',
// etc
]
]
];
我有一个使用模型 setConnection 更改连接属性的产品存储库:
I have a product repository which uses the Model setConnection to change the connection attribute :
public function setConnection($name) {
// assumes $this->product is your Product model
$this->product->setConnection($name);
}
然而,我发现它只适用于查询方法,而不适用于 Model::create ::
However, i found out that it only worked on query methods and not methods like Model::create ::
$productRepo = new ProductRepository();
foreach ($array as $key => $value) {
$productRepo->setConnection($key . '_' . $database);
// this works
$products = $productRepo->all();
// this doesn't work and will use the old connection
$product = $productRepo->create($data);
}
似乎一旦创建了实例,::create 方法就不会解析连接.有人知道修复吗?
Seems that the ::create method does not resolve the connection once the instance has been created. Anyone knows a fix?
推荐答案
问题是 setConnection()
作用于一个类的实例,但是 create()
> 方法是类本身的静态方法.在您的存储库中,$this->product
是 Product 类的一个实例.在执行查询之前在此实例上使用 setConnection()
会正常工作,但是如果您想在静态方法上使用单独的连接(例如 create()
).
The problem is that setConnection()
works on an instance of a class, but the create()
method is a static method on the class itself. In your repository, $this->product
is an instance of the Product class. Using setConnection()
on this instance before doing queries will work fine, but you'll need to do a little more manual work if you want to use separate connections on the static methods (such as create()
).
create()
方法所做的就是用给定的属性实例化一个新实例,然后调用 save()
.因此,无需在 Product 模型上调用 create()
,您只需手动执行此操作:
All the create()
method does is instantiate a new instance with the given attributes and then call save()
. So, instead of calling create()
on the Product model, you'll just need to do this manually:
class ProductRepository {
public function create(array $attributes, $connection = null) {
$product = $this->product->newInstance($attributes);
$product->setConnection($connection ?: $this->product->getConnectionName());
$product->save();
return $product;
}
}
您还可以覆盖 Product 模型上的静态 create()
方法以接受连接.
You could also override the static create()
method on the Product model to accept a connection, as well.
class Product extends Model {
public static function create(array $attributes, $connection = null) {
$model = new static($attributes);
$model->setConnection($connection ?: $this->connection);
$model->save();
return $model;
}
}
class ProductRepository {
public function create(array $attributes, $connection = null) {
$connection = $connection ?: $this->product->getConnectionName()
return $this->product->create($attributes, $connection);
}
}
相关文章