How to retrieve primary key of a dependent fixture?

Suppose I have a relation (1:1, 1:n, n:m). For example a User with a UserProfile where the profile_id is stored in the User model and is allowed to be NULL if the user has no profile. Lets further assume I have two fixture classes (UserFixture and UserProfileFixture respectively).

In my fixtures I would therefore declare UserFixture::$depends = [UserProfileFixture::class]. A data file for UserProfileFixture could then look as follows:

user_profile.php:

return [
  'profile-1' => ['gender' => 'male', 'birthday' => '1908-12-12 11:11:11'],
  'profile-2' => ['gender' => 'female', 'birthday' => '1910-10-10 12:12:12'],
];

However, I couldnā€™t find any information on how to retrieve the auto-generated primary-key from the data file of UserFixture:

user.php:

return [
  'user-1' => ['username' => 'User 1', 'profile_id' => ???],
];

How am I supposed to access auto-generated values (like primary key) from UserProfileFixture?
The best solution that I could think about was to set a singleton variable in beforeLoad() like this:

UserProfileFixture.php

public function beforeLoad()
{
    static::$instance = $this;
}

With this, I am able to retrieve the AR of profile-1 inside user.php as follows:

user.php:

$userProfile = UserProfileFixture::$instance;
return [
  'user-1' => ['username' => 'User 1', 'profile_id' => $userProfile->getModel('profile-1')],
];

Am I missing something, or is Yii really not providing access to the instances of dependent fixtures out of the box?

I think that you should specify the id field yourself for your user fixtures, like ā€œid => 1ā€, and then use that same id for the relationship.

Fixtures are meant to put your application in a fixed state, so you can also fixate your ids without problems.

That is correct. The downside of this approach is that this makes it a lot harder to actually edit and read fixtures, especially when writing fixtures for intermediate tables (n:m relations). I prefer to read self-documenting code rather than using ā€˜magic numbersā€™. Another downside is that I explicitly need to bypass the RDBMS mechanisms (which I may or may not want). For instance, I would like to rely on the default value for the user status when inserting data but still be able to access it in another fixture.

I am just wondering whether it was implemented on purpose that access to dependent fixutures is not provided out of the box (since Yii provides every mechanism necessary (see my workaround)). Or in other words: Is there a reason why anyone would not want access a dependent fixture like I did in my example?

1 Like

the fixtures provided by yii out of the box are very basic if you like to put logic in your fixtures create a command and you can pull in activerecord and go wild