<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # EloquentORM關聯關系之多對多 數據表之間往往不是孤立的,而是縱橫交叉、相互關聯的,比如一個用戶對應多個角色,一個角色擁有多個用戶等類似的多對多關聯。 ## 軟件版本 * Laravel Version 5.4.19 * PHP Version 7.0.8 ## 關鍵字和表 * `belongsToMany()` * `attach()` * `detach()` * `sync()` * `toggle()` * `roles` 、`role_user` 和 `users` 表 * `User` 、`Role` 和 `RoleUser` 模型 一種常見的關聯關系是多對多,即表A的某條記錄通過中間表 C 與表 B 的多條記錄關聯,反之亦然。比如一個用戶有多種角色,反之一個角色對應多個用戶。   比如用戶與角色組之間的關系,我們建立一個中間表 `role_user`,這個表關聯用戶表 `users` **(使用系統自帶的users表)** 和 `roles` 表,如下 ## 生成遷移文件和模型 ``` php artisan make:migration create_role_user_table --create=role_user php artisan make:model Role -m ``` ### 編輯遷移文件 文件 `<project>/database/migrate/*_create_users_table.php` 內容如下 ``` Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email',30)->unique(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); ``` 文件 `<project>/database/migrate/*_create_roles_table.php` 內容如下 ``` Schema::create('roles', function (Blueprint $table) { $table->increments('id')->comment('角色ID'); $table->string('name',20)->unique()->comment('角色英文名稱'); $table->char('display_name',20)->nullable()->comment('角色中文名稱'); $table->string('description',180)->nullable()->comment('角色簡要描述'); $table->timestamps(); }); ``` 文件 `<project>/database/migrate/*_create_role_user_table.php` 內容如下 ``` Schema::create('role_user' , function(Blueprint $table){ $table->unsignedInteger('user_id')->comment('用戶id,關聯users表'); $table->unsignedInteger('role_id')->comment('角色id,關聯roles表'); $table->foreign('user_id')->references('id')->on('users') ->onUpdate('cascade')->onDelete('cascade'); $table->foreign('role_id')->references('id')->on('roles') ->onUpdate('cascade')->onDelete('cascade'); $table->primary(['user_id' , 'role_id']); $table->timestamps(); }); ``` ### 運行 php artisan 命令保存修改到數據庫 ~~~ php artisan migrate ~~~ > 執行上面的命令后數據庫將生成五張表, > migrations > password_resets > users > roles > role_user ## 定義關聯關系和修改模型的 fillable 屬性 在 `User` 模型中定義與 `Role` 模型的對應關系: ``` public function roles() { /** * @param string $related 關聯關系 * @param string $table 關聯中間表 不填這里默認為 role_user 規則為:Str::snake(class_basename($related)). '_' . Str::snake(class_basename($this)) 并在數據拼接前使用 sort() 排序; * @param string $foreignKey 當前模型的外鍵id,不填默認為 user_id 規則為:Str::snake(class_basename($this)).'_'.$this->primaryKey; * @param string $relatedKey 關聯模型的外鍵id,不填默認為 role_id 規則為:Str::snake(class_basename($related)).'_'.$related->primaryKey * @param string $relation 關聯方法名 不填默認為roles */ return $this->belongsToMany('App\Role' , 'role_user' , 'user_id' , 'role_id' , 'roles')->withTimestamps(); } ``` 在 `Role` 模型中定義與 `User` 模型的關聯對應關系: ``` public function users() { /** * @param string $related 關聯關系 * @param string $table 關聯中間表 不填默認為 role_user 規則為:Str::snake(class_basename($related)). '_' . Str::snake(class_basename($this)) 并在數據拼接前使用 sort() 排序; * @param string $foreignKey 當前模型的外鍵id,不填默認為 role_id 規則為:Str::snake(class_basename($this)).'_'.$this->primaryKey; * @param string $relatedKey 關聯模型的外鍵id,不填默認為 user_id 規則為:Str::snake(class_basename($related)).'_'.$related->primaryKey * @param string $relation 關聯方法名 不填默認為 users */ return $this->belongsToMany(User::class , 'role_user' , 'role_id' , 'user_id' , 'users') ->withPivot(['created_at','updated_at']) // 中間表的字段,這里的中間表是 role_user ->withTimestamps(); } ``` > 如果想要中間表自動維護?`created_at`?和?`updated_at`?時間戳,可在定義關聯方法時加上?`withTimestamps()`?方法 ## 使用 tinker 填充數據 修改?`/databases/factories/ModelFactory.php`,新增關聯數據。 ~~~ /** @var \Illuminate\Database\Eloquent\Factory $factory */ $factory->define(App\User::class , function(Faker\Generator $faker){ static $password; return [ 'name' => $faker->name , 'email' => $faker->unique()->safeEmail , 'password' => $password ? : $password = bcrypt('secret') , 'remember_token' => str_random(10) , ]; }); $factory->define(App\Role::class , function(Faker\Generator $faker){ return [ 'name' => $faker->name , 'display_name' => $faker->name , 'description' => $faker->text(150) , ]; }); $factory->define(App\RoleUser::class , function(Faker\Generator $faker){ $user_ids = \App\User::pluck('id')->toArray(); $role_ids = \App\User::pluck('id')->toArray(); return [ 'user_id' => $faker->randomElement($user_ids) , 'role_id' => $faker->randomElement($role_ids) ]; }); ~~~ 使用 tinker 命令 ~~~ php artisan tinker ## 進入到 tinker 界面執行如下命令 namespace App factory(User::class,4)->create(); // 生成4個用戶 factory(Role::class,4)->create() // 生成4條 role_user 表的測試數據 ~~~ ## 關聯操作 ### 新增數據 #### 將用戶關聯到角色 ``` $role_id = 2; $user = \App\User::find(1); $user->roles()->attach($role_id); ``` #### 將用戶批量放入到角色 ``` $role_ids = [1,3,4]; $user = \App\User::find(1); $user->roles()->attach($role_ids); // $user->roles()->attach([1 => ['attribute1' => 'value1'], 2, 3]); ``` 有時可能想要使用一個命令,在建立新模型數據的同時附加關聯。可以使用?`save`方法達成目的: ~~~ $role = new Role(['name' => 'Editor']); \App\User::find(1)->roles()->save($role); ~~~ 上面的例子里,新的?`Role`?模型對象會在儲存的同時關聯到?`user`?模型。也可以傳入屬性數組把數據加到關聯數據庫表: ~~~ \App\User::find(1)->roles()->save($role, ['field' => 'value']); ~~~ ### 查詢數據 查詢用戶所擁有的角色 ``` $user = \App\User::find(1); $roles = $user->roles; dd($roles->toArray()); ``` 查詢角色下屬的所有用戶 ``` $role = \App\Role::find(2); $users = $role->users; ``` ### 關聯刪除 將用戶從角色中移除 ``` $role_id = 1; $user = \App\User::find(1); $user->roles()->detach($role_id); ``` 將用戶從所有角色中移除 ``` $user = \App\User::find(1); $user->roles()->detach(); ``` 刪除角色下的所有用戶關聯數據 ``` $role = \App\Role::find(2); $role->users()->delete(); ``` ### 更新數據 #### 把用戶"同步"到角色中 也可以使用?`sync`?方法附加關聯模型。?`sync`?方法會把根據 ID 數組把關聯存到中間表。附加完關聯后,中間表里的模型只會關聯到 ID 數組里的 id。 ``` $user = \App\User::find(1); $user->roles()->sync([1,2,4]); $user->roles()->sync([1 => ['field' => 'value']]); // 加入其他字段的數據 ``` #### 把角色"同步"給用戶 ``` $role = \App\Role::find(3); $role->users()->sync([1]); ``` > 如果在定義 `belongsToMany()` 關聯關系的時候,同時想操作中間關聯表的數據,這里指的是`role_user`?表,那么可以定義 `with->withPivot($columns)` (參數填寫中間表的字段) 那么,我們可以在使用 `attach()` 方法的時候傳入第二個參數進行數據的同步更新,例如: > ``` > dd($user->roles()->attach($role_id,['created_at'=>'2019-04-24 06:08:22'])); > ``` > 當然,如果單獨需要更新中間表,這里指的是`role_user` 表的字段,可以使用 `updateExistingPivot()`,例如: > ``` > $role_id = 2; > $user = \App\User::find(1); > $user->roles()->updateExistingPivot($role_id,['created_at'=>'2019-04-24 06:08:22']); > ``` ### 一些方法 #### `toggle` 顧名思義,如果表中存在則刪除數據,如果表中不存在則新增數據。運用場景比如:點贊、喜歡或踩等切換操作。 ``` $role_id = 2; // 入參 integer | array $user = \App\User::find(1); $user->roles()->toggle($role_id); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看