Я ищу чистое решение для запроса и изменения динамических свойств моей модели Eloquent, хранящихся в другой таблице.
Моя основная модель User
. User
может иметь несколько UserVariable
. При загрузке модели через UserRepository
я могу или не могу с нетерпением загружать переменные.
Чего я хочу добиться, так это того, что UserVariable
можно изменять в памяти и автоматически сохранять, когда и только когда сохраняется User
.
Вот мое решение (удалены ненужные части), которое работает, но не является ни элегантным, ни масштабируемым:
/**
* @property boolean $isCommentingEnabled
*/
class User extends \Illuminate\Database\Eloquent\Model
{
public function variables()
{
return $this->hasMany('UserVariable', 'var_userid', 'user_id');
}
public function getIsCommentingEnabledAttribute()
{
foreach ($this->variables as $variable) {
if ($variable->name == UserVariable::IS_COMMENTING_ENABLED) {
return (boolean) $variable->value;
}
}
return false;
}
public function setIsCommentingEnabledAttribute($enabled)
{
foreach ($this->variables as $variable) {
if ($variable->name == UserVariable::IS_COMMENTING_ENABLED) {
$variable->value = $enabled ? 1 : 0;
return;
}
}
$this->variables()->add(new UserVariable([
'name' => UserVariable::IS_COMMENTING_ENABLED,
'value' => $enabled ? 1 : 0,
]));
}
}
/**
* @property-read int $id Unique ID of the record.
* @property string $name Must be one of the constants in this class.
* @property int $userId
* @property string $value
*/
class UserVariable extends EloquentModel {}
class UserRepository
{
public function findById($id)
{
return User::with('variables')->find($id);
}
public function saveUser(User $user)
{
return $user->push();
}
}
Это решение явно не масштабируется. Если бы у пользователя было 5+ переменных, кода было бы много, даже если бы я извлек циклы.
Я подозреваю, что в Laravel должно быть короткое и чистое решение, чтобы просто вывести User
UserVariable
по имени или получить новое, если оно не существует, изменить его значение и вернуть его в модель. Когда вызывается User::push()
, он сохраняется автоматически. Сделанный.
Я ищу что-то вроде
$user->variables()->where('name', UserVariable::IS_COMMENTING_ENABLED)->first()->value
= $enabled ? 1 : 0;
Но вышеописанное не работает должным образом, потому что использует БД, а не модель. Любая помощь приветствуется.
Примечание. Я работаю над большой базой устаревшего кода, поэтому об изменении структуры БД пока не может быть и речи.