Задать вопрос

Как правильно устанавливается связь hasOne через SaveRelationsBehavior?

Привет! Использую в своем проекте удобный пакет SaveRelationsBehavior для работы со связями. Все вроде бы отлично работает, за исключением hasOne.

Суть. Сразу скажу, смысла в коде не ищите. Важна сама логика.

Значит у нас есть UserServie, User, UserProfile.

User:
class User extends \yii\db\ActiveRecord implements IdentityInterface
{

public function behaviors() {
        return [
            'saveRelations' => [
                'class'     => SaveRelationsBehavior::class,
                'relations' => ['profile'],
            ],
        ];
    }

public function rules() {
        return [
            [['profile'], 'safe']
        ];
    }

 public static function create($username) {
  $model = new static();
  $model->username = $username;
  retuqn $model;
 }

   public function getProfile() : ActiveQuery {
        return $this->hasOne(UserProfile::class,['user_id' => 'id']);
    }
}


UserProfile:
class UserProfile extends \yii\db\ActiveRecord
{
 public static function create() {
  return new static();
 }
}


UserService:
$user = User::create($username);
$user->profile = UserProfile::create();
$this->repository->save($user);


При таком подходе юзер успешно создается и так же успешно создается связь профиля с юзером. Тут все отлично.

НО!! При попытке создать профиль у УЖЕ существующего юзера возникает баг. К примеру:

UserService:
$user = User::findOne(1);
$user->profile = UserProfile::create();
$this->repository->save($user);


Если существует к примеру юзер и у него нету профиля, НО его пытаешься досоздать через реляцию - $user->profile = UserProfile::create(); В таком случае связь тоже создается, но в таблице юзеров у юзера меняется id на 0, а в таблице профиля связь создается, но user_id так же равно 0.

Эту проблему решить можно если в UserProfile передать user_id:

class UserProfile extends \yii\db\ActiveRecord
{
 public static function create($userId) {
  $model = new static();
  $model->user_id = userId;
  return $model;
 }
}


Однако, я не понимаю тогда почему при создании юзера с профилем связь отлично проставляется, а при попытке добавить у существующего юзера профиль происходит такой баг. С чем это связано?

Если же поменять реляцию на hasMany:

public function getProfile() : ActiveQuery {
        return $this->hasMany(UserProfile::class,['user_id' => 'id']);
    }


а в UserService поменять так, при этом Не передавать в UserProfile $user_id ($model->user_id = userId):
$user = User::findOne(1);
$profile = $user->profile;
$profile[] = UserProfile::create();
$user->profile = $profile;
$this->repository->save($user);


то связь тоже отлично создается. То есть полю user_id автоматом присваивается id юзера.

Еще раз. смысла в коде не ищите, вместо UserProfile может быть любой объект. Важно понять почему такая работа через hasOne.....

UPD. В общем эту проблему уже поднимали.
  • Вопрос задан
  • 64 просмотра
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы