Laravel/Ardent/User模型的编辑和保存

4

在laravel/ardent中,编辑带有密码的用户模型的预期方式是什么?我的问题是,在用户输入正确验证之前,我不想从数据库加载实际的用户模型。当我将密码字段留空时,验证显然会失败,因为密码是必需的。这是我的当前后编辑操作:

public function postEdit($id)
{
    // ardent autohydrates this model
    $newUser = new User;

    // validation fails
    if(!$newUser->validate())
        return Redirect::action('UsersController@getEdit', $id)
            ->with('error', Lang::get('Bitte Eingabe überprüfen'))
            ->withErrors($newUser->errors())
            ->withInput(Input::except('password'));

    // load model from db
    $exUser = User::find($id);
    if(!$exUser->exists)
        return Response::make('No such user', 500);

    // save model, ardent autohydrates again?
    if($exUser->save())
        return Redirect::action('UsersController@getShow', $id)
            ->with('success', Lang::get('Änderungen gespeichert'));
    else
        return Redirect::action('UsersController@getEdit', $id)
            ->with('error', Lang::get('Bitte Eingabe überprüfen'))
            ->withErrors($newUser->errors())
            ->withInput(Input::except('password'));
}

这段代码似乎很长(而且还不能正常工作),我无法找到一个适用于这种情况的示例。

2个回答

2

好的,我已经自己解决了问题,因为这不是一个非常活跃的话题。

问题在于结合ardent自动填充功能和保留旧密码的独特要求,如果没有提供新密码,则需要保留旧密码。因为ardent会在validate()save()时自动填充,所以无法阻止自动填充空密码。首先,我尝试更改输入数组并用旧密码覆盖它,但后来我简单地关闭了用户模型的自动填充功能:

class User extends Ardent implements UserInterface, RemindableInterface {

    public $forceEntityHydrationFromInput = false;
    public $autoHydrateEntityFromInput = false;

这是POST请求的编辑操作:

public function postEdit($id)
{
    // manually insert the input
    $user = new User(Input::all());

    // validate the user with special rules (password not required)
    if($user->validate(User::$updateRules)) {

        // get user from database and fill with input except password
        $user = User::find($id);
        $user->fill(Input::except('password'));

        // fill in password if it is not empty
        // will flag the pw as dirty, which will trigger rehashing on save()
        if(!empty(Input::get('password')))
            $user->password = Input::get('password');

        if($user->save())
            return Redirect::action('UsersController@getIndex')
                ->with('success', Lang::get('Änderungen gespeichert'));
    }

    return Redirect::action('UsersController@getEdit', $id)
        ->with('error', Lang::get('Bitte Eingaben überprüfen'))
        ->withErrors($user->errors())
        ->withInput(Input::except('password'));
}

1

我遇到了和你一样的问题。在不断搜索后,我阅读了Ardent代码,并得出了以下结论。它允许您使用一组规则、自动水合、自动哈希密码和Ardent的updateUnique()函数。我知道它可以被整理得更好,我相信有更好的方法来做到这一点,但我已经花费了太多时间在这个问题上。

这个方法使用控制器中的动态beforeSave()闭包(此处有文档)。由于我们正在进行更新操作,所以我们检查是否有密码被发送。如果没有密码,则将$rules数组中的密码验证设置为空,排除密码验证。由于自动哈希密码发生在验证之后并且在beforeSave()之前,所以我们需要关闭它(设置为false)。模型在通过验证后第二次传播,因此提交的空密码字段将在beforeSave()之前发出哈希,使其不再为空,并且将无法通过第二次检查。当运行updateUniques() 'or Save()'时,我们通过beforeSave闭包再次检查是否有密码被提交,如果没有,则从更新中删除它。

简而言之,使用最少的代码防止Ardent自动水合在管理更新时要求和/或删除密码。

模型:

class User extends Ardent implements UserInterface, RemindableInterface {

use UserTrait, RemindableTrait;

// Auto Hydrate
public $autoHydrateEntityFromInput   = true;
public $forceEntityHydrationFromInput   = true;
public $autoPurgeRedundantAttributes    = true;
// Auto hash passwords
public static $passwordAttributes  = array('password');
public $autoHashPasswordAttributes = true;

protected $table  = 'users';
protected $guarded  = array('id','created_at','updated_at');
protected $hidden = array('password');
protected $fillable = array('first_name','last_name','employee_id','position','email','password');

public static $rules = array(
    'first_name'            => 'required',
    'last_name'             => 'required',
    'employee_id'           => 'required|max:10',
    'position'              => 'required',
    'email'                 => 'required|email|unique',
    'password'              => 'required|alpha_num|min:6',
);

控制器:

public function update($id)
{
    $user = User::find($id);
    // Check if a password has been submitted
    if(!Input::has('password')){
    // If so remove the validation rule
      $user::$rules['password'] = '';
    // Also set autoHash to false;
      $user->autoHashPasswordAttributes = false;
    }
    // Run the update passing a Dynamic beforeSave() closure as the fourth argument
    if($user->updateUniques(
      array(),
      array(),
      array(),
      function($user){
    // Check for the presence of a blank password field again
        if(empty($user->password)){
    // If present remove it from the update
          unset($user->password);
          return true;
        }
      })
    ){
      Alert::success('User Updated')->flash();
      return Redirect::route('admin.users.index');
    }
        Alert::add('form','true')->flash();
    return Redirect::back()
      ->withInput(Input::except('password'))
      ->withErrors($user->errors());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接