I want to find or create user->settings relationship. I tried to use $this->hasOne(UserSettings::class)->withDefault();
, but this method returns new relationship while need I to create and store relationship with default values in DB and then return it. Is there any way to do so?
route
Route::get('settings', function (Request $request) {
return $request->user()->load('settings');
});
relation
public function settings()
{
return $this->hasOne(UserSettings::class)->withDefault( // I want to save row with this values in DB if it not exists and return it after
[
'backup_password' => '',
'backup_email' => '',
'codeword' => '',
'security_notifications' => 0,
'password_changed_at' => null,
'two_step_authentication' => 0
]);
}
UPD
I solved this problem like this, but I'm pretty sure that there is a better and cleaner solution
if(!($this->hasOne(UserSettings::class)->exists())) {
$settings = new UserSettings();
$settings->user_id = Auth::id();
$settings->backup_password = '';
$settings->backup_email = '';
$settings->codeword = '';
$settings->security_notifications = 0;
$settings->password_changed_at = null;
$settings->two_step_authentication = 0;
$settings->save();
}
return $this->hasOne(UserSettings::class);
A cleaner way would be for example
public function settings()
{
return $this->hasOne(UserSettings::class)->withDefault(function ($settings, $user) {
$settings->fill([
'backup_password' => '',
'backup_email' => '',
'codeword' => '',
'security_notifications' => 0,
'password_changed_at' => null,
'two_step_authentication' => 0,
]);
$user->settings()->save($settings);
});
}
Or even better if your default attributes are constant
In your UserSettings
model
/**
* The model's default values for attributes.
*
* @var array
*/
protected $attributes = [
'backup_password' => '',
'backup_email' => '',
'codeword' => '',
'security_notifications' => 0,
'password_changed_at' => null,
'two_step_authentication' => 0,
];
public function settings()
{
return $this->hasOne(UserSettings::class)->withDefault(function ($settings, $user) {
$user->settings()->save($settings);
});
}
It would be best to have a separate method on the user model which calls the existing relationship or creates a new relationship and saves it to the database. For example:
public function settings()
{
return $this->hasOne(UserSettings::class)->withDefault(
UserSettings::defaultAttributes()
);
}
// This checks to see if the relationship already exists within
// the database and if it does not then creates a new relationship,
// saves it to the database with the default attributes which you
// could make on the UserSettings model and then returns the user Model
// with the new settings.
public function loadOrCreateSettings()
{
if ( ! $this->settings()->exists()) {
$this->settings()->create(UserSettings::defaultAttributes());
}
return $this;
}
Doing it this way means your routes are cleaner and you are letting the User model handle the logic.
Route::get('settings', function (Request $request) {
return $request->user()->loadOrCreateSettings();
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.