只有用户模型使用空值保存到数据库

时间:2017-04-06 07:55:21

标签: php laravel eloquent laravel-5.4

在Laravel 5.4中,当我尝试将用户模型保存到数据库时,不保存值。我也设置了可填充属性。

它在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']
        ]);

然后将调用BaseModel的create方法,下面是它的代码。

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);
}

6 个答案:

答案 0 :(得分:7)

原因很可能是Laravel 5.4中的新中间件,称为“请求清理中间件”,如https://laravel.com/docs/5.4/releases中所述。

在app / Http / kernel.php中禁用\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,,看看你得到了什么。

您还可以检入/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);

如果字段可以为空,请在迁移文件中指明为f.ex. $table->string('all')->nullable();

如果完成,只需运行$user->save();

答案 1 :(得分:5)

create()

开始,Illuminate\Database\Eloquent\Model函数不再定义

处理为 dinamic方法调用,即通过调用其中一个函数(依赖于它是否静态调用):

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

Illuminate\Database\Eloquent\Model班。

现在我没有你的所有代码,但是,恕我直言,我会尝试在你的BaseModel类中改变这一行:

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

到此:

return $model->create($attributes);

或者,对我来说更好,对此:

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

答案 2 :(得分:2)

  

在   documentation   它说:

$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是什么,但应该是文档示例中的模型。

为什么你不使用资源控制器?或者,如果您需要填充数据库,请使用播种机 我认为这将更容易管理。

答案 3 :(得分:1)

所以我能想到的两件事

1,无需使用

protected $ guarded = [];

protected $ fillable = [];

如果不在这里,守卫会认为一切都是可填写的,并且可填写将假设一切都被保护,除非在这里。

引用文档

  

虽然$ fillable可用作白名单"对于应该可批量分配的属性,您也可以选择使用$ guarded。 $ guarded属性应包含一系列您不希望可批量分配的属性。不在数组中的所有其他属性将是可批量分配的。因此,$ guards功能就像一个"黑名单"。当然,你应该使用$ fillable或$ guarded - 而不是两者。

第二个排除任何$ this->模型的东西尝试首先实例化该类并保存它们

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();

答案 4 :(得分: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上添加了构造,这也导致了问题。所以,如果我删除,一切都将像以前一样工作。

答案 5 :(得分:1)

是的,您无法在Traits中使用__construct方法。

请参阅PHP.net以获取有关特性的更多详细信息,他们说"在__construct方法上使用AS(可能还有其他魔术方法)确实非常非常糟糕。"

您可以使用以下方式使用特征。

class User extends BaseModel
{
    use userRelation
}

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

我创建了" userRelation"特征包含很少有用的代码可以重复使用。

请参阅以下链接了解更多详情 - http://php.net/manual/en/language.oop5.traits.php

请尝试一下,如果它不能正常工作,请告诉我。 感谢