更新 Laravel 的 Eloquent 中的一对多关系
Updating a One-To-Many Relationship in Laravel's Eloquent
假设我在 Laravel 的 Eloquent 中有以下两个模型之间的关系:
<?php
// user:
// - user_id
class User extends Model
{
protected $table = 'users';
public function settings()
{
return $this->hasMany('Setting');
}
public function settingSet($key, $value)
{
\Setting::setConfigItem($key, $value, $this->user_id);
}
}
// settting:
// - setting_key
// - setting_value
// - user_id
class Setting extends Model
{
public function setConfigItem($key, $value, $user_id)
{
// Note: I've provided this code here as an example, so it should
// exist here only as pseudo-code - it has not been tested and
// is outside the scope of this issue but has been requested by
// a commenter so I've provided the basis for this method:
$existing = \Setting::where(['key' => $key, 'user_id' => $user_id])->first();
if (!$existing) {
\Setting::insert([ 'setting_key' => $key, 'setting_value' => $value, 'user_id' => $user_id ]);
} else {
$existing->setting_value = $value;
$existing->save();
}
}
}
我想检索单个用户及其设置,我可以执行以下操作:
<?php
$user = User::with(['setting'])->find(1);
现在,有了这个用户,我可以使用上面列出的 settingSet
方法更新或插入设置。
<?php
$user->settingSet('foo','bar');
但是,如果我此时检索设置,我将得到过时的数据。
<?php
print_r($user->settings); // onoes!
在 User::settingSet
方法或其他类似方法中的 INSERT/UPDATE/DELETE 之后强制更新此关系的数据的最佳做法是什么?
您遇到此问题是因为使用查询生成器而不是 eloquent,我不明白您为什么要同时使用两者,如果您使用的是 eloquent,那么请使用 eloquent,如果您使用查询生成器使用查询生成器,但不要同时使用两者,至少在你有可能不使用时不要使用。
我发现 setConfigItem
方法没用,因为您不是将用户推送到设置中,而是将设置推送到用户中,因此基本上所有实现都应该针对用户 class 而不是设置 class
清除后,你可以尝试做这样的事情 -
public function settingSet($key, $value)
{
$setting = new Setting([
'setting_key' => $key,
'setting_value' => $value
]);
$this->settings()->save($setting);
}
您还可以改进此方法,而不是一次只接受 1 个设置,您可以接受一组设置
顺便说一句,您不使用 pivot table 是有原因的吗?每个用户的设置都是唯一的吗?
您可以使用Lazy Eager Loading
、load()
函数强制更新数据。
print_r($user->load('settings'));
假设我在 Laravel 的 Eloquent 中有以下两个模型之间的关系:
<?php
// user:
// - user_id
class User extends Model
{
protected $table = 'users';
public function settings()
{
return $this->hasMany('Setting');
}
public function settingSet($key, $value)
{
\Setting::setConfigItem($key, $value, $this->user_id);
}
}
// settting:
// - setting_key
// - setting_value
// - user_id
class Setting extends Model
{
public function setConfigItem($key, $value, $user_id)
{
// Note: I've provided this code here as an example, so it should
// exist here only as pseudo-code - it has not been tested and
// is outside the scope of this issue but has been requested by
// a commenter so I've provided the basis for this method:
$existing = \Setting::where(['key' => $key, 'user_id' => $user_id])->first();
if (!$existing) {
\Setting::insert([ 'setting_key' => $key, 'setting_value' => $value, 'user_id' => $user_id ]);
} else {
$existing->setting_value = $value;
$existing->save();
}
}
}
我想检索单个用户及其设置,我可以执行以下操作:
<?php
$user = User::with(['setting'])->find(1);
现在,有了这个用户,我可以使用上面列出的 settingSet
方法更新或插入设置。
<?php
$user->settingSet('foo','bar');
但是,如果我此时检索设置,我将得到过时的数据。
<?php
print_r($user->settings); // onoes!
在 User::settingSet
方法或其他类似方法中的 INSERT/UPDATE/DELETE 之后强制更新此关系的数据的最佳做法是什么?
您遇到此问题是因为使用查询生成器而不是 eloquent,我不明白您为什么要同时使用两者,如果您使用的是 eloquent,那么请使用 eloquent,如果您使用查询生成器使用查询生成器,但不要同时使用两者,至少在你有可能不使用时不要使用。
我发现 setConfigItem
方法没用,因为您不是将用户推送到设置中,而是将设置推送到用户中,因此基本上所有实现都应该针对用户 class 而不是设置 class
清除后,你可以尝试做这样的事情 -
public function settingSet($key, $value)
{
$setting = new Setting([
'setting_key' => $key,
'setting_value' => $value
]);
$this->settings()->save($setting);
}
您还可以改进此方法,而不是一次只接受 1 个设置,您可以接受一组设置
顺便说一句,您不使用 pivot table 是有原因的吗?每个用户的设置都是唯一的吗?
您可以使用Lazy Eager Loading
、load()
函数强制更新数据。
print_r($user->load('settings'));