Laravel Nova indexQuery 范围重用
Laravel Nova indexQuery scopes reuse
我的应用程序确实有基于策略的权限管理,我正在使用 Nova 作为应用程序的后端。
现在 nova 内一切正常,我想为我的外部应用程序设置一个额外的 API。
我确实必须为我的大部分资源覆盖 indexQuery
,因为用户只能访问有限的范围,例如对于 Customer
资源:
public static function indexQuery(NovaRequest $request, $query)
{
$user = Auth::user();
// Admins and office users can see all customers
if($user->authorizeRoles(['admin', 'office'])) {
return $query;
}
// A user can only see customers associated with a job they work on
$query
->select('customers.*')
->join('jobs', 'jobs.customer_id', '=', 'customers.id')
->join('teams', 'jobs.team_id', '=','teams.id')
->join('team_user', 'teams.id', '=', 'team_user.team_id')
->where('team_user.user_id', '=', $user->id);
return $query;
}
现在,对于 API,我基本上需要相同的范围,我想知道将这段代码放在哪里。我的第一个想法是向 Customer
模型添加一个范围,因此我将添加一个带有参数的范围:
/**
* Limit the results to the customers the user is able to see
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \App\User $user
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeVisibleToUser($query, $user) {
if($user->authorizeRoles(['admin', 'office'])) {
return $query;
}
// A user can only see customers associated with a job they work on
$query
->select('customers.*')
->join('jobs', 'jobs.customer_id', '=', 'customers.id')
->join('teams', 'jobs.team_id', '=','teams.id')
->join('team_user', 'teams.id', '=', 'team_user.team_id')
->where('team_user.user_id', '=', $user->id);
return $query;
}
有没有什么方法可以在 indexQuery
方法中应用范围而不创建虚拟客户对象?
use App\Customer as AppCustomer;
/**
* Build an "index" query for the given resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function indexQuery(NovaRequest $request, $query)
{
$user = Auth::user();
return (new AppCustomer())->scopeVisibleToUser($query, $user);
}
Using real-time facades, you may treat any class in your application
as if it were a facade.
use Facades\App\Customer as AppCustomer;
/**
* Build an "index" query for the given resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function indexQuery(NovaRequest $request, $query)
{
$user = Auth::user();
return AppCustomer::visibleToUser($query, $user);
}
我的应用程序确实有基于策略的权限管理,我正在使用 Nova 作为应用程序的后端。
现在 nova 内一切正常,我想为我的外部应用程序设置一个额外的 API。
我确实必须为我的大部分资源覆盖 indexQuery
,因为用户只能访问有限的范围,例如对于 Customer
资源:
public static function indexQuery(NovaRequest $request, $query)
{
$user = Auth::user();
// Admins and office users can see all customers
if($user->authorizeRoles(['admin', 'office'])) {
return $query;
}
// A user can only see customers associated with a job they work on
$query
->select('customers.*')
->join('jobs', 'jobs.customer_id', '=', 'customers.id')
->join('teams', 'jobs.team_id', '=','teams.id')
->join('team_user', 'teams.id', '=', 'team_user.team_id')
->where('team_user.user_id', '=', $user->id);
return $query;
}
现在,对于 API,我基本上需要相同的范围,我想知道将这段代码放在哪里。我的第一个想法是向 Customer
模型添加一个范围,因此我将添加一个带有参数的范围:
/**
* Limit the results to the customers the user is able to see
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \App\User $user
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeVisibleToUser($query, $user) {
if($user->authorizeRoles(['admin', 'office'])) {
return $query;
}
// A user can only see customers associated with a job they work on
$query
->select('customers.*')
->join('jobs', 'jobs.customer_id', '=', 'customers.id')
->join('teams', 'jobs.team_id', '=','teams.id')
->join('team_user', 'teams.id', '=', 'team_user.team_id')
->where('team_user.user_id', '=', $user->id);
return $query;
}
有没有什么方法可以在 indexQuery
方法中应用范围而不创建虚拟客户对象?
use App\Customer as AppCustomer;
/**
* Build an "index" query for the given resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function indexQuery(NovaRequest $request, $query)
{
$user = Auth::user();
return (new AppCustomer())->scopeVisibleToUser($query, $user);
}
Using real-time facades, you may treat any class in your application as if it were a facade.
use Facades\App\Customer as AppCustomer;
/**
* Build an "index" query for the given resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function indexQuery(NovaRequest $request, $query)
{
$user = Auth::user();
return AppCustomer::visibleToUser($query, $user);
}