我想检查食谱是否属于登录用户。我想最好的方法是中间件。
所以我创建了一个中间件:AuthRecipe,包含以下代码:
$repo = new RecipeRepository;
$recipe = $repo->getById($request->recipes);
if($recipe->user_id !== $request->user()->id)
{
return redirect()->to('/');
}
在RecipeController中,我使用中间件,如:
$this->middleware('auth.recipe', ['only' => ['update', 'edit', 'destroy']]);
这很好用,如果食谱不属于用户,则用户会被重定向到家中,但是......
现在我有重复的代码。如果配方属于用户,它将获得中间件内的配方,但也在控制器本身中。所以我已经知道了配方,并且不需要再次在控制器中获取配方。
当然,我可以在模型中使用一种方法。
public function auth() {
if($this->user_id !== Auth::user()->id) {
redirect()->to('/');
}
}
但是我必须为每个需要保护的方法调用该方法。我认为中间件更清洁。致电$recipe->auth()
并非真正的控制人责任。
有没有办法将配方数据从中间件传递给控制器?
答案 0 :(得分:1)
创意1:
您可以使用路线模型绑定:
根据Laravel文档:
Laravel路径模型绑定提供了一种将类实例注入路径的便捷方法。例如,您可以注入与给定ID匹配的整个User类实例,而不是注入用户的ID。
[...]
由于我们已将{user}参数绑定到App \ User模型,因此将在路由中注入User实例。因此,例如,对profile / 1的请求将注入ID为1的User实例。 ```
http://laravel.com/docs/5.1/routing#route-model-binding
通过这种方式,您可以加载模型一次并将其直接传递给控制器(假设它通过中间件)
修改强>
一旦模型绑定在路由的引导方法中,您就可以在控制器中访问它,如下所示:
public function getUser(\Illuminate\Http\Request $request)
{
//
}
创意2:
另一个想法是在第一次加载模型时缓存模型,然后您不必担心加载模型多次,因为它将从缓存加载。使用redis或memcache缓存非常快。
$user = Cache::rememberForever('user_'. $user_id, function() use ($user_id)
{
return User::find($user_id);
});
http://laravel.com/docs/5.1/cache
然而,这样做的缺点是,当对模型进行更改时,您需要清除缓存(可以使用事件/侦听器执行此操作)