Как передать аргументы фабрикам Laravel?

У меня есть таблица users и отношение один к нулю/один с таблицей businesses (users.user_id => business.user_id). В моей таблице users у меня есть дискриминатор, который сообщает мне, является ли пользователь бизнес-типом, и поэтому мне также нужны подробности о таблице businesses.

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

У меня в голове три варианта:

  1. Создайте из фабрики пользователей, а затем с помощью '->each()' выполните некоторые проверки дискриминатора и создайте нового бизнес-пользователя, используя фабрику. Однако я не могу передать бизнес-фабрике user_id, назначенный пользователю.
  2. Сначала создайте пользователей. Затем в моем сеялке для бизнеса найдите всех пользователей, которые соответствуют дискриминатору «бизнес». Затем для всех этих пользователей запустите фабрику, которая создает бизнес-детали. Но опять же, мне нужно было бы каким-то образом связать user_id уже созданного пользователя с бизнес-фабрикой user_id.
  3. В моей бизнес-фабрике создайте нового пользователя и получите идентификатор, таким образом установив связь между users.user_id и business.user_id. Однако я использую генератор случайных чисел для user.user_type, поэтому даже если у меня заполнена таблица businesses, это может быть для пользователей, у которых дискриминатор является «личным».

Есть ли другой способ? Могу ли я передавать аргументы из моего сеялки на фабрику?


person Cristian    schedule 03.09.2015    source источник


Ответы (2)


Атрибуты, которые вы передаете функции create, будут переданы в обратный вызов определения вашей модели в качестве второго аргумента.


В вашем случае вам даже не нужно обращаться к этим атрибутам, поскольку они будут автоматически объединены:

$business = factory(App\Business::class)->create();

factory(App\User::class, 5)->create([
    'business_id' => $business->id,
]);

Адаптируйте это к вашим потребностям.

person Joseph Silber    schedule 03.09.2015
comment
Как я мог это пропустить. Я смотрел урок Laracast и знаю, что сам помню, как настраивать вещи. Конечно, это было и в документации: laravel.com/docs/master/testing# фабрики моделей. Большое спасибо. - person Cristian; 03.09.2015
comment
Ссылка @Cristian сейчас выглядит устаревшей, для 5.4 см. laravel.com/docs/5.4/ database-testing#using-factories и прокрутите вниз до «Сохраняющиеся модели». - person Harry; 21.02.2017
comment
а как насчет этого? php $student->assignRole('student'); я использую spatie/permission - person Lloric Mayuga Garcia; 07.10.2017
comment
а если я не хочу их объединять? что, если я хочу использовать пользовательские параметры для моделирования фабрик? - person shotex; 08.10.2017
comment
@shotex - Если вам нужны настраиваемые параметры, почему вы используете фабрики? Просто создайте модель сами: User::create($attributes) - person Joseph Silber; 11.10.2017
comment
@JosephSilber В моем случае я хотел бы передать параметр $user, чтобы я мог получить его тип и, в соответствии с этим, получить связанное с ним случайное значение. - person Víctor; 11.10.2018
comment
Отлично, в руководстве сказано так: вы можете переопределить атрибуты модели, передав массив методу create. laravel.com/docs/5.8/database-testing#persisting-models - person PaulH; 12.03.2019

Мой код для добавления полиморфных пользователей «Администратор» был:

// run model factory
factory(App\Admin::class, 3)->create()->each(function ($admin) {

    $admin->user()->save(

        // solved: https://laravel.com/docs/master/database-testing#using-factories (Overriding attributes)
        factory(App\User::class)->make([
              'userable_id' => $admin->id,
              'userable_type' => App\Admin::class
        ])
    );
});

Надеюсь это поможет.

person Robin Hood    schedule 23.06.2019
comment
Привет, Робин, как я могу использовать переменную внутри фабрики? не переопределять напрямую - person George; 10.10.2019
comment
@George Тогда просто используйте make() без массива пользовательских значений для userable_id и userable_type. - person Robin Hood; 10.10.2019
comment
я хочу, чтобы переменную администратора можно было использовать в фабрике пользователей, например if( $admin->name == 'test'} do something - person George; 10.10.2019
comment
Затем вам нужно будет использовать класс Admin: $admin = new Admin(). ???? Начните с этого и посмотрите, что получится. - person Robin Hood; 12.10.2019
comment
есть ли способ получить доступ к $admin-›id внутри фабрики пользователей? - person vikrant; 03.11.2020
comment
@vikrant Я считаю, что $admin-›id работает только на фабрике администраторов. Я думаю, что для фабрики пользователей вам нужно жестко закодировать идентификатор администратора. - person Robin Hood; 05.11.2020