Skip to content

Instantly share code, notes, and snippets.

@guimossibento
Forked from Braunson/pivot-tables.md
Created December 18, 2021 16:35
Show Gist options
  • Save guimossibento/91ca38cdae88bb45e25923f4d244f00a to your computer and use it in GitHub Desktop.
Save guimossibento/91ca38cdae88bb45e25923f4d244f00a to your computer and use it in GitHub Desktop.

Revisions

  1. @Braunson Braunson revised this gist Feb 6, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion pivot-tables.md
    Original file line number Diff line number Diff line change
    @@ -164,7 +164,7 @@ Let's assume our `User` object has many `Role` objects that it is related to. Af
    $user = App\Models\User::first();

    foreach ($user->roles as $role) {
    echo $role->pivot->name; // This will echo out the role name
    echo $role->name; // This will echo out the role name
    }
    ```

  2. @Braunson Braunson revised this gist Sep 16, 2020. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions pivot-tables.md
    Original file line number Diff line number Diff line change
    @@ -176,23 +176,23 @@ foreach ($user->roles as $role) {

    As mentioned above, attributes from the intermediate table may be accessed on models using the pivot attribute. However, you can customize the name of this attribute to better reflect its purpose within your application.

    For example, if your application contains users that may subscribe to podcasts, you probably have a many-to-many relationship between users and podcasts. If this is the case, you may wish to rename your intermediate table accessor to `subscription` instead of `pivot`. This can be done using the `as` method when defining the relationship:
    For example, if your application contains users that may subscribe to multiple podcasts, you probably have a many-to-many relationship between users and podcasts. If this is the case, you may wish to rename your intermediate table accessor to `subscription` instead of `pivot`. This can be done using the `as` method when defining the relationship:

    ```php
    public function roles()
    public function podcasts()
    {
    return $this->belongsToMany(Role::class)
    ->as('positions');
    return $this->belongsToMany(Podcast::class)
    ->as('subscriptions');
    }
    ```

    Once this is done, you can access the intermediate table data using the customized name from above:

    ```php
    $users = App\Models\User::with('roles')->get();
    $users = App\Models\User::with('podcasts')->get();

    foreach ($users->flatMap->roles as $podcast) {
    echo $podcast->position->name; // This will echo out the role name
    foreach ($users->flatMap->podcasts as $podcast) {
    echo $podcast->name; // This will echo out the podcast name
    }
    ```

  3. @Braunson Braunson revised this gist Apr 24, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion pivot-tables.md
    Original file line number Diff line number Diff line change
    @@ -213,7 +213,7 @@ $user->roles()->attach($role->id);

    ### Adding Multiple Roles To a User

    This works the same as above when adding a role but you can pass an array of IDs to the `detach` method to remove multiple roles from a user.
    You can pass an array of IDs to the `attach` method to add multiple roles to a user.

    ```php
    $user = App\Models\User::first(); // John Doe
  4. @Braunson Braunson revised this gist Dec 21, 2019. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions pivot-tables.md
    Original file line number Diff line number Diff line change
    @@ -213,7 +213,7 @@ $user->roles()->attach($role->id);

    ### Adding Multiple Roles To a User

    This works the same as above when adding a role but you can pass an array of IDs to the `detatch` method to remove multiple roles from a user.
    This works the same as above when adding a role but you can pass an array of IDs to the `detach` method to remove multiple roles from a user.

    ```php
    $user = App\Models\User::first(); // John Doe
    @@ -238,21 +238,21 @@ $user->roles()->detach($role->id);

    ### Removing Multiple Roles From a User

    This works the same as above when adding a role but you can pass an array of IDs to the `detatch` method to remove multiple roles from a user.
    This works the same as above when adding a role but you can pass an array of IDs to the `detach` method to remove multiple roles from a user.

    ```php
    $user = App\Models\User::first(); // John Doe
    $roles = App\Models\Role::all()->pluck('id'); // Admin, User

    // Removes MULTIPLE roles to the user
    $user->roles()->detatch($roles);
    $user->roles()->detach($roles);
    ```



    ### Syncing Roles

    There's a method called `sync` that accepts new vales as an array of IDs and will take care of the syncing of roles. The result is that no mater what values were in the table prior to running `sync`, after the code is run there will only be these `role` IDs attached to the user. It will remove any not in this list that are in the database and add any that aren't in the database but that are in this list.
    There's a method called `sync` that accepts new vales as an array of IDs and will take care of the syncing of roles. The result is that no matter what values were in the table prior to running `sync`, after the code is run there will only be these `role` IDs attached to the user. It will remove any not in this list that are in the database and add any that aren't in the database but that are in this list.

    ```php
    $user = App\Models\User::first();
    @@ -279,4 +279,4 @@ $user->roles()->attach($role->id, ['added_by' => 'Braunson']);

    ## Wrapping up

    There's a bunch more things you can do with relations and they are documented in the [Laravel documentation](https://laravel.com/docs/6.x/eloquent-relationships#many-to-many). The goal of this writeup was to establish a basic understanding and usage with pivot tables in Laravel.
    There's a bunch more things you can do with relations and they are documented in the [Laravel documentation](https://laravel.com/docs/6.x/eloquent-relationships#many-to-many). The goal of this write-up was to establish a basic understanding and usage with pivot tables in Laravel.
  5. @Braunson Braunson revised this gist Nov 22, 2019. 1 changed file with 4 additions and 5 deletions.
    9 changes: 4 additions & 5 deletions pivot-tables.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Laravel 6 - Diving into Pivot Tables
    # Laravel 6 - Diving Into Pivot Tables

    Pivot tables can be confusing and a little hard to wrap your head around at first. In this quick article we are going to dive into what a pivot table is, how to create one and finally how to use the pivot table. Let's dive in!

    @@ -25,11 +25,10 @@ Let's create two tables which we need to use the `Many To Many` relationship for
    - (Pivot) Table: `user_roles`



    **The `users` table will look something like this:**

    - `id` (INT)
    - `name` (VARCHAR)
    - `id` (INT)
    - `name` (VARCHAR)

    **The `roles` table will look like this:**

    @@ -43,7 +42,7 @@ Let's create two tables which we need to use the `Many To Many` relationship for



    ##Using Pivot Tables
    ## Using Pivot Tables

    So now that we've gone over the structure of the two tables and our `pivot` table, let's dig into how to use them!

  6. @Braunson Braunson created this gist Nov 22, 2019.
    283 changes: 283 additions & 0 deletions pivot-tables.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,283 @@
    # Laravel 6 - Diving into Pivot Tables

    Pivot tables can be confusing and a little hard to wrap your head around at first. In this quick article we are going to dive into what a pivot table is, how to create one and finally how to use the pivot table. Let's dive in!



    ## What is a pivot table?

    A pivot table is used to connect relationships between two tables. Laravel provides a `Many To Many` relationship where you can use a **pivot table**.



    ## The use of a pivot table

    In the example next, we will review how a `users` table and a `roles` table are joined together with a `user_roles` pivot table. Pivot tables allow you to (in this case) add multiple `roles` to a `user`.



    ## Example of a Pivot Table

    Let's create two tables which we need to use the `Many To Many` relationship for.

    - Table: `users`
    - Table: `roles`
    - (Pivot) Table: `user_roles`



    **The `users` table will look something like this:**

    - `id` (INT)
    - `name` (VARCHAR)

    **The `roles` table will look like this:**

    - `id` (INT)
    - `name` (VARCHAR)

    **Now our <u>pivot table</u> `user_roles` will look like this:**

    - `user_id` (INT)
    - `role_id` (INT)



    ##Using Pivot Tables

    So now that we've gone over the structure of the two tables and our `pivot` table, let's dig into how to use them!

    ### Creating The Pivot Table's Migration

    The migration should look like this, it establishes the proper columns and foreign key relations to both the `users` and `roles` table. The migration will also set both `user_id` and `role_id` as the primary keys so there cannot be duplicates with both the same `user_id` and `role_id`.

    ```php
    <?php

    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;

    class CreateUserRolesTable extends Migration
    {
    /**
    * Run the migrations.
    *
    * @return void
    */
    public function up()
    {
    Schema::create('user_roles', function (Blueprint $table) {
    $table->integer('user_id')->unsigned()->index();
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    $table->integer('role_id')->unsigned()->index();
    $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
    $table->primary(['user_id', 'role_id']);
    });
    }

    /**
    * Reverse the migrations.
    *
    * @return void
    */
    public function down()
    {
    Schema::dropIfExists('user_roles');
    }
    }
    ```



    ### Setting Up The Model Relations

    We will open our `User.php` and `Role.php` models and define the relations needed in both models.

    ```php
    <?php

    namespace App\Models;

    use App\Models\Role;
    use Illuminate\Notifications\Notifiable;
    use Illuminate\Foundation\Auth\User as Authenticatable;

    class User extends Authenticatable
    {
    use Notifiable;

    /*
    * The roles that belong to this user
    */
    public function roles()
    {
    return $this->belongsToMany(Role::class);
    }
    }
    ```

    ```php
    <?php

    namespace App\Models;

    use App\Models\User;
    use Illuminate\Database\Eloquent\Model;

    class Role extends Model
    {
    /*
    * The users that belong to this role
    */
    public function users()
    {
    return $this->belongsToMany(User::class);
    }
    }
    ```



    ### Defining Your Custom Intermediate Table

    If you want to define the custom model that represents the pivot or intermediate table of your relation, you can call the `using` method when defining the relationship. Note that custom `Many To Many` pivot models should extend the `Illuminate\Database\Eloquent\Relations\Pivot` class. For example, we want to define a Role which uses a custom `UserRole` pivot model:

    ```php
    <?php

    namespace App\Models;

    use Illuminate\Database\Eloquent\Relations\Pivot;

    class UserRole extends Pivot
    {
    //
    }
    ```



    ### Retrieving a User's Role

    Let's assume our `User` object has many `Role` objects that it is related to. After accessing this relationship, we may access the intermediate table using the `pivot` attribute on the models.

    ```php
    $user = App\Models\User::first();

    foreach ($user->roles as $role) {
    echo $role->pivot->name; // This will echo out the role name
    }
    ```

    > Notice that each `Role` model we retrieve is automatically assigned a `pivot` attribute. This attribute contains a model representing the intermediate table, and may be used like any other Eloquent model.


    ### Customizing The `pivot` Attribute Name

    As mentioned above, attributes from the intermediate table may be accessed on models using the pivot attribute. However, you can customize the name of this attribute to better reflect its purpose within your application.

    For example, if your application contains users that may subscribe to podcasts, you probably have a many-to-many relationship between users and podcasts. If this is the case, you may wish to rename your intermediate table accessor to `subscription` instead of `pivot`. This can be done using the `as` method when defining the relationship:

    ```php
    public function roles()
    {
    return $this->belongsToMany(Role::class)
    ->as('positions');
    }
    ```

    Once this is done, you can access the intermediate table data using the customized name from above:

    ```php
    $users = App\Models\User::with('roles')->get();

    foreach ($users->flatMap->roles as $podcast) {
    echo $podcast->position->name; // This will echo out the role name
    }
    ```

    > You may be asking what **`flatMap`** does in the above code example. It's a [Collection helper](https://laravel.com/docs/5.8/collections#method-flatmap). Eloquent returns a `Collection` on a relation by default. We use `flatMap` in the example to iterate through the collection and pass each value to the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items. Then, the array is flattened by a level (which is what we want in this case).


    ### Adding A Role To A User

    ```php
    $user = App\Models\User::first(); // John Doe
    $role = App\Models\Role::first(); // Admin

    $user->roles()->attach($role->id);
    ```



    ### Adding Multiple Roles To a User

    This works the same as above when adding a role but you can pass an array of IDs to the `detatch` method to remove multiple roles from a user.

    ```php
    $user = App\Models\User::first(); // John Doe
    $roles = App\Models\Role::all()->pluck('id'); // Admin, User

    // Adds MULTIPLE roles to the user
    $user->roles()->attach($roles);
    ```



    ### Removing A Role From A User

    ```php
    $user = App\Models\User::first(); // John Doe
    $role = App\Models\Role::first(); // Admin

    $user->roles()->detach($role->id);
    ```



    ### Removing Multiple Roles From a User

    This works the same as above when adding a role but you can pass an array of IDs to the `detatch` method to remove multiple roles from a user.

    ```php
    $user = App\Models\User::first(); // John Doe
    $roles = App\Models\Role::all()->pluck('id'); // Admin, User

    // Removes MULTIPLE roles to the user
    $user->roles()->detatch($roles);
    ```



    ### Syncing Roles

    There's a method called `sync` that accepts new vales as an array of IDs and will take care of the syncing of roles. The result is that no mater what values were in the table prior to running `sync`, after the code is run there will only be these `role` IDs attached to the user. It will remove any not in this list that are in the database and add any that aren't in the database but that are in this list.

    ```php
    $user = App\Models\User::first();
    $roles = App\Models\Role::all()->pluck('id');

    // $roles will provide an array of role IDs that will be synced to the user
    $user->roles()->sync($roles);
    ```



    ### Attaching a Role with Additional Parameters

    Sometimes you may want to add additional parameters when attaching a `role` to a `user`. Let's take a look at an example on how to do this. In this example, assume the Administrator is assigning a user a new role but they want to specify who it was added by (just a string for simplicity sake, assume `added_by` is a column on the `user_roles` table alongside `user_id` and `role_id`).

    ```php
    $user = App\Models\User::first(); // John Doe
    $role = App\Models\Role::find(2); // User

    $user->roles()->attach($role->id, ['added_by' => 'Braunson']);
    ```



    ## Wrapping up

    There's a bunch more things you can do with relations and they are documented in the [Laravel documentation](https://laravel.com/docs/6.x/eloquent-relationships#many-to-many). The goal of this writeup was to establish a basic understanding and usage with pivot tables in Laravel.