只有用户模型将空值保存到数据库
Only User Model is saving with empty Values to database
在 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);
}
从 5.4 开始,create()
函数不再在 Illuminate\Database\Eloquent\Model
中定义:
作为动态方法调用处理,即通过调用这些函数之一(取决于它是否被静态调用):
public static function __callStatic($method, $parameters)
// or
public function __call($method, $parameters)
在Illuminate\Database\Eloquent\Model
class.
现在我没有你的所有代码,但是恕我直言,我会尝试更改你的 BaseModel 中的这一行 class:
return parent::query()->create($attributes);
对此:
return $model->create($attributes);
或者,对我来说更好的是:
return (new static)->newQuery()->create($attributes);
In the
documentation
it says:
$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()
是您的 public 函数,但我不知道您的情况下 $this
是什么,但应该是文档示例中的模型。
为什么不使用资源控制器?或者,如果您需要填充数据库,请使用播种机
我觉得会更容易管理。
原因很可能是 Laravel 5.4 中的新中间件称为 "Request Sanitization Middleware",如 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();
所以我可以考虑 2 件事
1st没有必要用
受保护的 $guarded = [];
和
受保护的 $fillable = [];
Guarded 将假定所有内容都可填充(如果不在此处),而 fillable 将假定所有内容都受到保护,除非在这里。
引用文档
While $fillable serves as a "white list" of attributes that should be mass assignable, you may also choose to use $guarded. The $guarded property should contain an array of attributes that you do not want to be mass assignable. All other attributes not in the array will be mass assignable. So, $guarded functions like a "black list". Of course, you should use either $fillable or $guarded - not both.
第 2 次排除任何 $this->model 的东西尝试先实例化 class 并保存它们
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();
伙计们,我可以使用 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 特征上添加了构造,这也导致了问题。所以如果我删除它,一切都会像以前一样工作。
是的,您不能在 Traits 中使用 __construct 方法。
请参阅 PHP.net 以了解有关特征的更多详细信息,他们说 "Using AS on a __construct method (and maybe other magic methods) is really, really bad."
你可以像下面这样使用特征。
class User extends BaseModel
{
use userRelation
}
Trait userRelation
{
public function getUserName()
{
return "Jhon Doe";
}
}
我创建了 "userRelation" Trait,其中包含一些有用的代码以供重复使用。
详情请参考以下link - http://php.net/manual/en/language.oop5.traits.php
请试一试,如果不行请告诉我。
谢谢
在 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);
}
从 5.4 开始,create()
函数不再在 Illuminate\Database\Eloquent\Model
中定义:
作为动态方法调用处理,即通过调用这些函数之一(取决于它是否被静态调用):
public static function __callStatic($method, $parameters)
// or
public function __call($method, $parameters)
在Illuminate\Database\Eloquent\Model
class.
现在我没有你的所有代码,但是恕我直言,我会尝试更改你的 BaseModel 中的这一行 class:
return parent::query()->create($attributes);
对此:
return $model->create($attributes);
或者,对我来说更好的是:
return (new static)->newQuery()->create($attributes);
In the documentation it says:
$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()
是您的 public 函数,但我不知道您的情况下 $this
是什么,但应该是文档示例中的模型。
为什么不使用资源控制器?或者,如果您需要填充数据库,请使用播种机 我觉得会更容易管理。
原因很可能是 Laravel 5.4 中的新中间件称为 "Request Sanitization Middleware",如 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();
所以我可以考虑 2 件事
1st没有必要用
受保护的 $guarded = [];
和
受保护的 $fillable = [];
Guarded 将假定所有内容都可填充(如果不在此处),而 fillable 将假定所有内容都受到保护,除非在这里。
引用文档
While $fillable serves as a "white list" of attributes that should be mass assignable, you may also choose to use $guarded. The $guarded property should contain an array of attributes that you do not want to be mass assignable. All other attributes not in the array will be mass assignable. So, $guarded functions like a "black list". Of course, you should use either $fillable or $guarded - not both.
第 2 次排除任何 $this->model 的东西尝试先实例化 class 并保存它们
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();
伙计们,我可以使用 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 特征上添加了构造,这也导致了问题。所以如果我删除它,一切都会像以前一样工作。
是的,您不能在 Traits 中使用 __construct 方法。
请参阅 PHP.net 以了解有关特征的更多详细信息,他们说 "Using AS on a __construct method (and maybe other magic methods) is really, really bad."
你可以像下面这样使用特征。
class User extends BaseModel
{
use userRelation
}
Trait userRelation
{
public function getUserName()
{
return "Jhon Doe";
}
}
我创建了 "userRelation" Trait,其中包含一些有用的代码以供重复使用。
详情请参考以下link - http://php.net/manual/en/language.oop5.traits.php
请试一试,如果不行请告诉我。 谢谢