A
A
Alexey Sklyarov2020-09-20 22:31:02
Laravel
Alexey Sklyarov, 2020-09-20 22:31:02

How to correctly link two models to a pivot table?

There are models:

  • User - user model
  • Role - role model
  • RoleSettings - a model of settings corresponding to a specific role

Database model:
Open Image
5f67aacb4c78a364042421.png


The logic of work is the following:
  1. Creating Roles
    Role::create([
            "name" => "Пользователь",
            "slug" => "user"
          ]);


  2. We create role settings that will then be added to each user who has the corresponding role (for example, the user can enable / disable notification of comments in a thread, and the administrator enable / notify notification of new posts by mail)
    RoleSettings::create([
            'setting_title' => 'Уведомлять о новых ответах в комментариях',
            'setting_slug' => 'comment_reply_enabled',
            'role_id' => Role::where('slug','user')->first()->id
          ]);


  3. Adding a role to a user
    $role = Role::where('slug','user')->first();
    $user->role()->attach($role);


  4. Next, I need to add from the roles_settings table to the users_settings table all entries whose role_id is equal to the role_id of the user, and specify the corresponding user id for these entries.
    So far it's implemented like this:
    /**
          * Прикрепляем пользователю роль по умолчанию (пользователь)
          */
          $user_settings = [];
          $role_settings = RoleSettings::where('role_id',1)->get();
    
          foreach ($role_settings as $role_setting) {
            $user_settings[$role_setting->id] = ['value' => $role_setting->default_value];
          }
    
          $user->settings()->attach($user_settings);




In principle, this works, but the user object will be like this:
Show object
"id": 1,
        "name": "Sklyarov Alexey",
        "email": "---",
        "email_verified_at": null,
        "current_team_id": null,
        "profile_photo_path": "profile-photos/mU1dOnx7YhDWY5OEAxRKgkijwRghRW7XgI7Rp5IT.jpeg",
        "created_at": "2020-09-19T12:22:28.000000Z",
        "updated_at": "2020-09-19T12:26:46.000000Z",
        "profile_photo_url": "http://localhost/storage/profile-photos/mU1dOnx7YhDWY5OEAxRKgkijwRghRW7XgI7Rp5IT.jpeg",
        "settings": [
            {
                "id": 1,
                "role_id": 1,
                "setting_title": "Уведомлять о новых ответах в комментариях",
                "setting_slug": "comment_reply_enabled",
                "default_value": 1,
                "pivot": {
                    "user_id": 1,
                    "setting_id": 1,
                    "value": "1"
                }
            },
            {
                "id": 2,
                "role_id": 1,
                "setting_title": "Уведомлять о новых ответах на почту",
                "setting_slug": "comment_reply_mail_enabled",
                "default_value": 1,
                "pivot": {
                    "user_id": 1,
                    "setting_id": 2,
                    "value": "1"
                }
            }
        ],


That is, the information that I need initially is in pivot. Obviously this has to do with how I associate the role settings with the user. In the User model, I do it like this:
/**
    * Получить настройки пользователя
    */
    public function settings()
    {
      return $this->belongsToMany(RoleSettings::class,'users_settings','user_id','setting_id')->withPivot('value');
    }


I don't understand how to link these models adequately.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
Y
Yuri Kulaxyz, 2020-09-21
@Kulaxyz

See how it is implemented in ready-made packages, for example here
If I understand correctly, then this decision falls on your needs.

A
anlamas, 2020-09-22
@anlamas

You linked the models correctly.
Additional pivot table data will be in pivot.
There is no problem accessing this data:

// Условимся, что settings не пустой
$user->settings[0]->pivot->value

// Можешь переименовать
$this->belongsToMany(RoleSettings::class,'users_settings','user_id','setting_id')
->withPivot('value')
->as('info');
// После писать так
$user->settings[0]->info->value

В общем, у тебя все ок.
<a href="https://laravel.com/docs/8.x/eloquent-relationships#many-to-many">Many to many</a>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question