0
public function store()
{
  $input = Input::all();
  $validator = User::validate($input);

  if(!$validator->passes()) {
    $notification['danger'] = 'There were validation errors!';
    return Redirect::route('user.create')->withInput()->withErrors($validator)->with('notification', $notification);
  }

  $input['password'] = Hash::make($input['password']);
  $user = $this->user->create($input);
  $role = $this->role->find($input['role_id']);
  $user->roles()->save($role);

  $notification['success'] = "User $user->email sucessfuly created.";
  return Redirect::route('user.index')->with('notification', $notification);    
}

所以我一直在阅读很多关于架构的文章,虽然我意识到这不是“好”的做事方式,但我想不出很多解决方案。

将其提取到 UserRepository UserFormValidator 等一堆类中听起来像是过度工程,特别是在我的情况下,它是一个相当小的项目,只会持续几周。

我更感兴趣的是如何将这个业务逻辑提取到我的用户模型中。在我看来,通过关系关联其他模型无论如何都是模型的关注点。我当前的模型代码只设置了 hasMany()、belongsTo() 等关系以及 $filleable、$hidden 属性。

无论如何,我愿意接受建议。

4

2 回答 2

0

因为这是一个小项目,并且您正在考虑将代码移动到用户模型中,所以这里有一段可以重构的代码:

代替:

  $role = $this->role->find($input['role_id']);
  $user->roles()->save($role);

写:

       $role = $this->role->find($input['role_id']);
       $user->addRole($role);

在您的用户模型中:

class User extends Eloquent
{
   public function addRole($role)
   {
          if(!is_null($role) and is_object($role) and $role->id > 0)
          {
              return    $this->roles()->save($role);
          }
          else
          {
               throw new RoleNotFoundException($role);
          }
   }
}

然后在你的 global.php 文件中为这种类型的异常定义一个错误处理程序:

App::error(function(RoleNotFoundException $exception)
{
    // Handle the exception...
    return Response::make('Error! ' . $exception->getCode());
});

这将使您的代码更具可读性和健壮性,并且在实现方法时使您无需记住 Laravel 的细节,这就是您将它们包装在 User 模型中的原因。在这个例子中它相当简单,但这种方法可以在更复杂的场景中为您省去很多麻烦。

于 2013-10-19T10:11:53.400 回答
0

在存储库之前,这是我用来创建和验证模型的方式:

public function store()
{
    $user = new User(Input::all());

    $user->password = Input::get('password');

    if( !$user->save() ) {
        return Redirect::back()
                ->withInput()
                ->withErrors($user->errors);
    }

    return Redirect::route('users.index')
        ->with('successMessages', 'User "'.$user->first_name.'" created.');
}

此代码由

一个基本模型:

use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;

class BaseModel extends Eloquent {

    public $errors;

    public function __construct(array $attributes = array()) {

        parent::__construct($attributes);

    }

    public static function boot() {
        parent::boot();

        static::saving(function ($data) {
            return $data->validate();
        });
    }

    public function validate() {

        $validation = Validator::make($this->attributes, $this->rules);

        if($validation->passes()) return true;

        $this->errors = $validation->messages();

        return false;

    }

}

通过在启动时创建保存事件,您可以验证模型并在 save() 上返回 true 或 false;

用户模型:

use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;

class User extends BaseModel implements UserInterface, RemindableInterface {
    protected $table = 'users';

    public $guarded =   [   
                            'password',
                            'password_confirmation',
                        ];

    public $rules = array(
                            'first_name' => 'required|min:3',
                            'last_name' => 'required|min:3',
                            'email' => 'required|min:6',
                        );

    protected $hidden = array('password');

    public function setPasswordAttribute($string) 
    {

        $this->attributes['password'] = Hash::make($string);
    }

}

还有我的一些代码layout.blade.php

@if( Session::has('errors') )
    You have some errors:

    @foreach( Session::get('errors')->all() as $error )
        <div class="alert alert-block alert-error fade in">
            <button data-dismiss="alert" class="close" type="button">×</button>
            <p>{{ $error->message }}</p>
        </div>
    @endforeach
@endif

@if( isset($successMessage) ) 
    <div class="alert alert-block alert-success fade in">
        <button data-dismiss="alert" class="close" type="button">×</button>
        <p>{{ $successMessage }}</p>
    </div>
@endif

@if( isset($errorMessage) ) 
    <div class="alert alert-block alert-error fade in">
        <button data-dismiss="alert" class="close" type="button">×</button>
        <p>{{ $errorMessage }}</p>
    </div>
@endif

实际上,这个刀片代码并没有那么大,它由一些刀片 _partials 和一个模板帮助器类提供,看起来更像这样:

{{ Template::notifications('error', Session::get('errors')) }}
{{ isset($successMessage) ? Template::notify('success', $successMessage) : '' }}
{{ isset($errorMessage) ? Template::notify('error', $errorMessage) : '' }}

使用验证,您可以节省一些行,并且永远不需要记住再次验证您的输入。

于 2013-10-19T11:40:16.217 回答