我开始开发一个SaaS应用程序,并且已经创建了我的数据库结构。我计划创建一个中间件文件来处理该请求的数据库连接。在这个中间件文件中,我想创建一个模型,它将始终只选择与当前连接cust_id
(外键)对应的任何表中的行。
$Customers->where('cust_id', $cust_id)->first();
我如何做到这一点,而不必在每个选择语句中指定where('cust_id', $cust_id)
?
您可以在您的模型中使用Eloquent的全局查询范围轻松实现这一点。你可以在这里阅读更多关于他们的信息:http://laravel.com/docs/5.1/eloquent#query-scopes
首先,您需要定义Multitenant作用域类,它将更新运行的所有查询并在cust_id字段上添加约束:class MultitenantScope implements ScopeInterface
{
public function apply(Builder $builder, Model $model)
{
if (Auth::id()) {
$builder->whereCustId(Auth::id());
} else {
$model = $builder->getModel();
// apply a constraint that will never be true
// so that no records are fetched for unauthorized users
$builder->whereNull($model->getKeyName());
}
}
public function remove(Builder $builder, Model $model)
{
$query = $builder->getQuery();
$query->wheres = collect($query->wheres)->reject(function ($where) {
return ($where['column'] == 'cust_id');
})->values()->all();
}
}
然后你需要一个trait,你将添加到需要被过滤的模型中:
trait MultitenantTrait
{
public static function bootMultitenantTrait()
{
static::addGlobalScope(new MultitenantScope());
}
public static function allTenants()
{
return (new static())->newQueryWithoutScope(new MultitenantScope());
}
}
最后一部分是将MultitenantTrait添加到您的模型:
class SomeModel extends Eloquent {
use MultitenantTrait;
}
现在,每次使用Eloquent的模型方法执行任何查询时,cust_id约束将应用于查询,并且只有属于给定cust_id的模型才可用。
如果出于某种原因需要访问所有对象,可以使用allTenants()方法来运行查询,而不需要附加约束:
$allRows = SomeModel::allTenants()->get();
请记住,我还没有测试过确切的代码,所以让我知道,如果你看到任何问题,我会很高兴为你工作:)