清除检查资源是否存在的方式以及用户是否可以编辑它

时间:2014-05-01 15:28:09

标签: laravel laravel-4

我有两个非常常见的步骤,我必须在我的控制器中的几乎每个CRUD方法中重复这些步骤。我将我的用户拆分为2组( Users, Administrators )。现在,用户可以edit, update and delete只有自己的条目,而管理员可以执行所有CRUD操作。

我每次发现自己写的第二段代码是检查资源是否存在,这是重复的,有点烦人。

以下是我的尝试:

<?php

class BaseController extends Controller
{
  // Received Eloquent model each model has user_id field
  public function authorize($resource)
  {
    // Check if currently logged in users id matches user_id
    // value of the resource
    if($resource->user_id !== CurrentUser::getUser()->id)
    {
      // Users id does not match with resource user_id check if user is admin
      if(!CurrentUser::getGroup() === 'Admin')
      {
        // The id's do not match and user is not admin redirect him back to root
        Session::flash('error', 'You cannot edit this resource');
        return Redirect::to('/');
      }
    }
  }  
} 

class CarController extends BaseController
{
  public function edit($id)
  {
    // Attempt to find the resource
    $car = Car::find($id);

    // Check if found
    if(!$car)
    {
      // Resource was not found
      Session::flash('error', 'Resource was not found');
      return Redirect::to('/cars');
    }

    // First check if user is allowed to edit the resource
    // this however does not work because returned Redirect is simply ignored I would
    // have to return boolean and then check it but...
    $this->authorize($car); 

    // ... rest of the code
  }
}

如果我有3-4种方法,这不会有问题,但我有6-10种方法,你可以看到这部分需要大约20行代码加6到10次,更不用说它了#39;重复到令人讨厌的程度。

我尝试使用过滤器解决问题,但问题是我可以将id传递给过滤器,但不能让它以我传递模型的方式工作。

必须有一种更清洁的方式来实现这一切。我对authorize函数/进程感到有些满意,但是每次可能都有一些过滤器并且每个控制器都会定义需要授权的全局变量/数组方法时,不必调用就太棒了。

至于检查是否找到了记录,我希望可以使用过滤器来捕获所有RecordNotFound异常,并通过消息重定向回控制器索引路由。

1 个答案:

答案 0 :(得分:3)

你可以使用findOrFail()并在BaseController中捕获异常,你也有两个选择:

try
{
    $post = $this->post->findOrFail($id);

    return View::make('posts.show', compact('post'));
}
catch(ModelNotFoundException $e)
{
    return Redirect::route('posts.index');
}

或者

$post = $this->post->findOrFail($id);

return View::make('posts.show', compact('post'));

一个异常处理程序返回到您的表单,输入:

App::error(function(ModelNotFoundException $exception)
{
    return Redirect::back()->withErrors()->withInput();
});

请注意,这些只是示例,而不是从您的代码中获取。