前言 本文以「一個使用者擁有多個專案和多筆文章」為例,為關聯模型建立資料填充。
關聯方法 首先,為 User 模型建立 projects() 和 posts() 關聯方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public  function  projects (    return  $this ->hasMany (Project ::class ); } public  function  posts (    return  $this ->hasMany (Post ::class ); } 
做法一 以父模型為主,由上而下建立關聯資料。
首先,建立一個 UserSeeder 資料填充,建立 5 個使用者,為每個使用者建立 10 個專案和 10 筆文章。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 use  App \Post ;use  App \Project ;use  App \User ;use  Illuminate \Database \Seeder ;class  UserSeeder  extends  Seeder          public  function  run (      {        factory (User ::class , 5 )->create ()->each (function ($user ) {             $user ->projects ()->saveMany (factory (Project ::class , 10 )->make ());             $user ->posts ()->saveMany (factory (Post ::class , 10 )->make ());         });     } } 
此方法將所有模型都寫在同一個檔案,在互相關聯的情況下,很容易寫出複雜的巢狀結構,不易維護。
做法二 將模型工廠生成的測試資料儲存在靜態屬性中,讓測試資料可以在不同的 Seeder 之間分享。
首先,在 App\Traits 資料夾建立一個 HasStaticAttributes 特徵機制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 trait  HasStaticAttributes          private  static  array  $attributes  = [];          private  function  setAttribute (string  $key , $value       {        self ::$attributes [$key ] = $value ;     }          private  function  getAttribute (string  $key       {        return  self ::$attributes [$key ] ?? null ;     }          public  function  set (string  $key , $value       {        $this ->setAttribute ($key , $value );     }          public  function  get (string  $key       {        return  $this ->getAttribute ($key );     }          public  function  __set (string  $key , $value       {        $this ->setAttribute ($key , $value );     }          public  function  __get (string  $key       {        return  $this ->getAttribute ($key );     }          public  function  __call ($method , $parameters       {        return  $this ->getAttribute ($method );     } } 
建立一個 UserSeeder 資料填充,引入特徵機制,建立 5 個使用者:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 use  App \User ;use  App \Traits \HasStaticAttributes ;use  Illuminate \Database \Seeder ;class  UserSeeder  extends  Seeder     use  HasStaticAttributes ;     private  const  AMOUNT  = 5 ;          public  function  run (      {        $this ->users = factory (User ::class , self ::AMOUNT )->create ();     } } 
建立一個 ProjectSeeder 資料填充,引入特徵機制,從 UserSeeder 取得測試資料,並為每個使用者建立 10 個專案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 use  App \Project ;use  App \Traits \HasStaticAttributes ;use  Illuminate \Database \Seeder ;class  ProjectSeeder  extends  Seeder     use  HasStaticAttributes ;     private  const  AMOUNT  = 10 ;          public  function  run (      {        app (UserSeeder ::class )->users->each (function ($user ) {             $user ->projects ()->saveMany (factory (Project ::class , self ::AMOUNT )->make ());         });     } } 
建立一個 PostSeeder 資料填充,引入特徵機制,從 UserSeeder 取得測試資料,並為每個使用者建立 10 筆文章。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 use  App \Post ;use  App \Traits \HasStaticAttributes ;use  Illuminate \Database \Seeder ;class  PostSeeder  extends  Seeder     use  HasStaticAttributes ;     private  const  AMOUNT  = 10 ;          public  function  run (      {        app (UserSeeder ::class )->users->each (function ($user ) {             $user ->posts ()->saveMany (factory (Post ::class , self ::AMOUNT )->make ());         });     } } 
此方法避免將所有模型都寫在同一個檔案內,而是利用靜態屬性分享測試資料,靈活度比較高。