{"action":"created","issue":{"url":"https://api.github.com/repos/laravel/framework/issues/12231","repository_url":"https://api.github.com/repos/laravel/framework","labels_url":"https://api.github.com/repos/laravel/framework/issues/12231/labels{/name}","comments_url":"https://api.github.com/repos/laravel/framework/issues/12231/comments","events_url":"https://api.github.com/repos/laravel/framework/issues/12231/events","html_url":"https://github.com/laravel/framework/pull/12231","id":132650563,"number":12231,"title":"[5.2] Prevent related models proliferation on ModelFactory","user":{"login":"micc83","id":1750404,"avatar_url":"https://avatars.githubusercontent.com/u/1750404?v=3","gravatar_id":"","url":"https://api.github.com/users/micc83","html_url":"https://github.com/micc83","followers_url":"https://api.github.com/users/micc83/followers","following_url":"https://api.github.com/users/micc83/following{/other_user}","gists_url":"https://api.github.com/users/micc83/gists{/gist_id}","starred_url":"https://api.github.com/users/micc83/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/micc83/subscriptions","organizations_url":"https://api.github.com/users/micc83/orgs","repos_url":"https://api.github.com/users/micc83/repos","events_url":"https://api.github.com/users/micc83/events{/privacy}","received_events_url":"https://api.github.com/users/micc83/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-02-10T09:45:33Z","updated_at":"2016-02-10T15:15:13Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/laravel/framework/pulls/12231","html_url":"https://github.com/laravel/framework/pull/12231","diff_url":"https://github.com/laravel/framework/pull/12231.diff","patch_url":"https://github.com/laravel/framework/pull/12231.patch"},"body":"Allows to define closures within the model factory definition in order to avoid unused models to be written to the database when overriding the model attributes. (See #9245)\r\n\r\nHere's a model definition example:\r\n\r\n```php\r\n$factory->define(App\\Post::class, function ($faker) {\r\n    return [\r\n        'title' => $faker->title,\r\n        'content' => $faker->paragraph,\r\n        'user_id' => factory(App\\User::class)->create()->id\r\n    ];\r\n});\r\n```\r\n\r\nIf you overwrite the `user_id` attribute when creating an instance of the model:\r\n\r\n```php\r\n$post = factory(App\\Post::class)->create([ 'user_id' => App\\User::find(1)]);\r\n```\r\n\r\nYou'll end up having written an unused `App\\User` model to the database as the attribute merging happens after the evaluation of the definition.\r\n\r\nThe first fix has been provided by @devinfd with #9387 and looked something like this:\r\n\r\n```php\r\n$factory->define(App\\Post::class, function ($faker, $attributes) {\r\n    $userId = isset($attributes['user_id']) ? $attributes['user_id']: factory(App\\User::class)->create()->id;\r\n    return [\r\n        'title' => $faker->title,\r\n        'content' => $faker->paragraph,\r\n        'user_id' => $userId\r\n    ];\r\n});\r\n```\r\n\r\nThis works but as you start defining more complex model relationship becomes ugly as hell.\r\n\r\nMy solution is to provide the ability to insert relationship model definition inside a closure and evaluate the closure only after the attributes merging.\r\n\r\nSo you will declare the definition as follow:\r\n\r\n```php\r\n$factory->define(App\\Post::class, function ($faker) {\r\n    return [\r\n        'title' => $faker->title,\r\n        'content' => $faker->paragraph,\r\n        'user_id' => function () {\r\n            return factory(App\\User::class)->create()->id;\r\n        }\r\n    ];\r\n});\r\n```\r\n\r\nAn array of evaluated definition is passed to the  closure in order to define complex relationships:\r\n\r\n```php\r\n$factory->define(App\\Post::class, function ($faker) {\r\n    return [\r\n        'title' => $faker->title,\r\n        'content' => $faker->paragraph,\r\n        'user_id' => function () {\r\n            return factory(App\\User::class)->create()->id;\r\n        },\r\n        'user_type' => function (array $evaluated) {\r\n            return App\\User::find($evaluated['user_id'])->type;\r\n        }\r\n    ];\r\n});\r\n```"},"comment":{"url":"https://api.github.com/repos/laravel/framework/issues/comments/182419045","html_url":"https://github.com/laravel/framework/pull/12231#issuecomment-182419045","issue_url":"https://api.github.com/repos/laravel/framework/issues/12231","id":182419045,"user":{"login":"micc83","id":1750404,"avatar_url":"https://avatars.githubusercontent.com/u/1750404?v=3","gravatar_id":"","url":"https://api.github.com/users/micc83","html_url":"https://github.com/micc83","followers_url":"https://api.github.com/users/micc83/followers","following_url":"https://api.github.com/users/micc83/following{/other_user}","gists_url":"https://api.github.com/users/micc83/gists{/gist_id}","starred_url":"https://api.github.com/users/micc83/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/micc83/subscriptions","organizations_url":"https://api.github.com/users/micc83/orgs","repos_url":"https://api.github.com/users/micc83/repos","events_url":"https://api.github.com/users/micc83/events{/privacy}","received_events_url":"https://api.github.com/users/micc83/received_events","type":"User","site_admin":false},"created_at":"2016-02-10T15:15:13Z","updated_at":"2016-02-10T15:15:13Z","body":"@GrahamCampbell I've replace the `foreach` loop with `array_map` but I'm not sure what you mean with \"Please import this.\""}}