Только модель пользователя сохраняет с пустыми значениями в базе данных

В Laravel 5.4, когда я пытаюсь сохранить модель User в базе данных, значения не сохраняются. Я также установил свойство fillable.

Он работал в Laravel 5.3. Эта проблема возникает после обновления приложения в Laravel 5.4.

Ниже представлена ​​модель пользователя.

class User extends BaseModel implements AuthenticatableContract, CanResetPasswordContract, JWTSubject
{
    use SoftDeletes,
        UserAccess,
        UserAttribute,
        UserRelationship,
        Authenticatable,
        CanResetPassword,
        Notifiable;

    /**
     * Database Table
     *
     * @var string
     */
    protected $table = "users";

    /**
     * The attributes that are not mass assignable.
     *
     * @var array
     */
    protected $guarded = ['id'];

    /**
     * Fillable Form Fields
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'first_name',
        'last_name',
        'email',
        'password',
        'status',
        'confirmed',
        'api_user',
        'confirmation_code',
        'account_id',
        'role_id',
        'cw_contact_id',
        'all',
        'all_locations',
        'username',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];

    /**
     * Select HTML Preference
     *
     * @var string
     */
    protected static $selectHTMLFormat = "[email]";

    /**
     * @var array
     */
    protected $dates = ['deleted_at', 'last_login'];
}

Обратите внимание, что проблема связана только с моделью пользователя.

Я сохраняю пользователя, как показано ниже.

// Create User
        $user = $this->model->create([
            'first_name'        => $input['first_name'],
            'last_name'         => $input['last_name'],
            'username'          => $input['username'],
            'email'             => $input['email'],
            'password'          => bcrypt($input['password']),
            'confirmation_code' => md5(uniqid(mt_rand(), true)),
            'confirmed'         => 1,
            'api_user'          => (isset($input['api_user']) ? $input['api_user'] : 0),
            'account_id'        => $input['account_id'],
            'role_id'           => (isset($input['role_id']) ? $input['role_id'] : 0),
            'all'               => (!isset($input['associated-permissions']) || $input['associated-permissions'] == 'all') ? 1 : 0,
            'status'            => (!isset($input['status']) || $input['status'] ? 1 : 0),
            'all_locations'     => $input['all_locations']
        ]);

Затем будет вызываться метод create BaseModel, а ниже - его код.

public static function create(array $attributes = Array())
{
    $user = access()->user();

    if($user)
    {
        $attributes['account_id'] = (!isset($attributes['account_id']) ? $user->account->id : $attributes['account_id'] );
    }

    $childClass     = get_called_class();
    $model          = new $childClass;
    $model->runActionLogger(false, 'create');

    return parent::query()->create($attributes);
}

Ответ 1

Ребята, я могу решить проблему с помощью метода Fill().

public static function create(array $attributes = Array())
{
    $user = access()->user();

    if($user)
    {
        $attributes['account_id'] = (!isset($attributes['account_id']) ? $user->account->id : $attributes['account_id'] );
    }

    $childClass     = get_called_class();
    $model          = new $childClass;

    $model->fill($attributes);
    $model->save();

    $model->runActionLogger($model, 'create');

    return $model;
}

Также по ошибке я добавил конструкцию CanResetPassword Trait, которая также вызывает проблему. Поэтому, если я удалю, все будет работать по-прежнему.

Ответ 2

Причиной является, скорее всего, новое промежуточное ПО в Laravel 5.4, называемое "Request Sanitization Middleware", как описано в https://laravel.com/docs/5.4/releases.

Отключить \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, в приложении /Http/kernel.php и посмотреть, что вы получаете.

Вы также можете проверить /config/database.php и настройки подключения mysql: 'strict' => true, если это так, установите false.

Хорошей практикой является использование модели для ввода пользователем. В этом случае вместо $user = $this->model->create(...) заполните модель с помощью $user = new \App\User($input) и обновите свои значения там, f.ex. $user->confirmation_code = md5(uniqid(mt_rand(), true)); и $user->password = bcrypt($user->password);

Если поля имеют значение NULL, укажите в файле миграции как таковой, f.ex. $table->string('all')->nullable();

Если сделано, просто запустите $user->save();

Ответ 3

В 5.4 функция create() не более определена в Illuminate\Database\Eloquent\Model:

Выполняется как вызов динамического метода, то есть путем вызова одной из этих функций (в зависимости от того, вызвана ли она статически или нет):

public static function __callStatic($method, $parameters)
// or
public function __call($method, $parameters)

В классе Illuminate\Database\Eloquent\Model.

Теперь у меня нет всего кода, но, IMHO, я попытаюсь изменить эту строку в классе BaseModel:

return parent::query()->create($attributes);

:

return $model->create($attributes);

или, еще лучше для меня:

return (new static)->newQuery()->create($attributes);

Ответ 4

В документацияон говорит:

$post = App\Post::find(1);

$comment = $post->comments()->create([
    'message' => 'A new comment.',
]);

Итак,

$user = $this->users()->create([
            'first_name'        => $input['first_name'],
            'last_name'         => $input['last_name'],
            'username'          => $input['username'],
            'email'             => $input['email'],
            'password'          => bcrypt($input['password']),
            'confirmation_code' => md5(uniqid(mt_rand(), true)),
            'confirmed'         => 1,
            'api_user'          => (isset($input['api_user']) ? $input['api_user'] : 0),
            'account_id'        => $input['account_id'],
            'role_id'           => (isset($input['role_id']) ? $input['role_id'] : 0),
            'all'               => (!isset($input['associated-permissions']) || $input['associated-permissions'] == 'all') ? 1 : 0,
            'status'            => (!isset($input['status']) || $input['status'] ? 1 : 0),
            'all_locations'     => $input['all_locations']
        ]);

где users() - ваша публичная функция, но я не знаю, что такое $this в вашем случае, но должно быть моделью, как в примере из документации.

Почему вы не используете контроллеры ресурсов? Или, если вам нужно заполнить db, используйте сеялку Я думаю, с ним будет легче справиться.

Ответ 5

Итак, 2 вещи, которые я могу придумать

В-первых, нет необходимости использовать

protected $guarded = [];

и

protected $fillable = [];

Охраненный будет считать, что все заполняется, если его не здесь и заполняемый будет считать, что все охраняется, если только здесь.

Чтобы процитировать документы

В то время как $fillable служит как "белый список" атрибутов, которые должны быть назначены массой, вы также можете использовать $guarded. Свойство $guarded должно содержать массив атрибутов, который вы не хотите назначать массе. Все остальные атрибуты, не входящие в массив, будут назначаться массами. Итак, $охраняемые функции, такие как "черный список". Конечно, вы должны использовать либо $fillable, либо $guarded - не оба.

2nd, чтобы исключить любой из $this- > model stuff, попробуйте сначала создать экземпляр класса и сохранить его

use App\Path\To\Model as user;

$user = new user();
$user->first_name    = $input['first_name'];
$user->last_name     = $input['last_name'];
$user->username      = $input['username'];
$user->email         = $input['email'];
$user->password      = bcrypt($input['password']);
$user->confirmation_code = md5(uniqid(mt_rand(); true));
$user->confirmed     = 1;
$user->api_user      = (isset($input['api_user']) ? $input['api_user'] : 0);
$user->account_id    = $input['account_id'];
$user->role_id       = (isset($input['role_id']) ? $input['role_id'] : 0);
$user->all           = (!isset($input['associated-permissions']) || $input['associated-permissions'] == 'all') ? 1 : 0;
$user->status        = (!isset($input['status']) || $input['status'] ? 1 : 0);
$user->all_locations = $input['all_locations'];
$user->save();

Ответ 6

Да, вы не можете использовать метод __construct в чертах.

Пожалуйста, обратитесь к PHP.net для получения дополнительной информации о признаке, они сказали: "Использование AS для метода __construct (и, возможно, других магических методов) действительно действительно плохо".

Вы можете использовать черту, как показано ниже.

class User extends BaseModel
{
    use userRelation
}

Trait userRelation
{
       public function getUserName()
       {
             return "Jhon Doe";
       }
}

Я создал "userRelation" Trait, который содержит несколько полезных кода для повторного использования.

Для получения дополнительной информации см. следующую ссылку - http://php.net/manual/en/language.oop5.traits.php

Пожалуйста, попробуйте и дайте мне знать, если это не сработает. Благодаря