Редактирование модели Laravel / Ardent / User + сохранение

каков предполагаемый способ редактирования модели пользователя с паролем в 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')); } 

это похоже на очень много кода (+ он не работает), я не смог найти пример для этой ситуации

Хорошо, решил сам, потому что это не очень активная тема.

Проблема заключалась в объединении функции автогидрации ardents и уникальном требовании сохранить старый пароль, если новый не указан. Поскольку пламенные автогидраты на validate() AND 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')); } 

Я столкнулся с тем же вопросом, что и вы. После того, как я навсегда искал, я прочитал Прочный код и придумал это. Он позволяет использовать один набор правил, автоматическое увлажнение, авто хэш-пароли и функцию updateUnique () для Ardent. Я знаю, что его можно очистить, и я уверен, что это лучший способ сделать это, но я уже потратил много времени на эту проблему.

Это использует динамическое закрытие beforeSave () в контроллере (описано здесь ). Поскольку мы обновляем, мы проверяем, отправляется ли пароль. Если пароль не установлен, то проверка пароля в массиве $ rules будет пустым, исключая пароль из проверки. Поскольку автоматические хеширующие пароли происходят после проверки и до beforeSave (), нам нужно отключить его (установить значение false). Модель распространяется во второй раз после прохождения проверки, поэтому отправленное пустое поле пароля будет выдано Hash до beforeSave (), делая его более незаполненным и не выполнит нашу вторую проверку. При запуске updateUniques () 'или Save ()' мы снова проверяем закрытие beforeSave, если вы отправляете пароль, а затем удаляете его из обновления.

tl; dr Предотвращает автоматическую гидратацию 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()); } с 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()); }