Laravel 8: Как создать сводную модель с соответствующей миграцией?

#laravel #migration #pivot-table #laravel-8 #laravel-models

#laravel #миграция #сводная таблица #laravel-8 #laravel-модели

Вопрос:

Я хотел бы создать модель: FormsUser и миграцию: forms_user

Чтобы использовать таблицу в качестве сводной, потому что у меня возникают проблемы при создании форм, мне говорят, что таблица: «forms_users не существует», потому что я создал миграцию отдельно, и когда я перехожу на страницу управления членами моей группы, я получаю сообщение об ошибке: «forms_users не существует», потому что здесь у меня естьчтобы использовать сводную таблицу, она должна иметь это имя таблицы…

Можете ли вы помочь мне решить эту проблему или предложить альтернативу? короче говоря, я хочу создать формы и создать команду, в которую я могу добавить другого пользователя в те же формы.

миграция: формы иamp; Модели форм :

 class Forms extends Model
{
    use HasFactory;
    use SoftDeletes;

    protected $fillable = [
        'title',
        'description',
        'date',
        'color',
        'progress',
        'user_id',
        'groupe_id',
        'formulaire',
        'logo',
    ];

    protected $dates = [
        'created_at',
        'deleted_at',
        'started_at',
        'update_at'
    ];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function usersGroupe()
    {
        return $this->belongsToMany(User::class);
    }
}
 

миграция: пользователи amp;amp; Модели пользователя:

 class User extends Authenticatable
{
    use HasApiTokens;
    use HasFactory;
    use HasProfilePhoto;
    use Notifiable;
    use TwoFactorAuthenticatable;
    use SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'lastname',
        'firstname',
        'email',
        'password',
        'current_team_id',
        'profile_photo_path',
        'role_id',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'two_factor_recovery_codes',
        'two_factor_secret',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = [
        'profile_photo_url',
        'role_id',
    ];

    protected $dates = [
        'created_at',
        'deleted_at',
        'started_at',
        'update_at'
    ];

    public function forms()
    {
        return $this->hasMany(Forms::class);
    }

    public function formGroupe()
    {
        return $this->belongsToMany(Forms::class);
    }

    public function role()
    {
        //return $this->hasMany(Role::class, 'id', 'role_id');
        return $this->hasOne(Role::class, 'id', 'role_id');
    }

    public function user()
    {
        return $this->hasOne(User::class);
    }
}
 

миграция: formuser amp;amp; Моделирует FormsUser :

 class FormsUser extends Model
{
    use HasFactory;

    protected $fillable = [
        'forms_id',
        'user_id'
    ];
}
 

миграция create_forms_user :

 Schema::create('forms_user', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->unsignedBigInteger('forms_id');
            $table->foreign('forms_id')->references('id')->on('forms');
            $table->unsignedBigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
        });
 

Комментарии:

1. почему у вас не работает сводная связь laravel по умолчанию? laraveldaily.com/pivot-tables-and-many-to-many-relationships

2. Пожалуйста, покажите свои модели и миграции…

3. Хорошо, я отредактирую вопрос, чтобы добавить их

Ответ №1:

Поэтому традиционно вам не нужно создавать сводную модель. В Laravel есть некоторые соглашения об именах, которые, если вы будете придерживаться, немного упростят задачу. Например, модели должны быть единственными, но имена таблиц должны быть множественными, за исключением сводной таблицы. Например, ваши модели должны выглядеть так:

 class User extends Model { ... }

class Form extends Model { ... }
 

Тогда ваши имена таблиц будут :

 users

forms

form_user
 

Сводная таблица должна содержать единственное имя каждой таблицы в алфавитном порядке. Итак, F стоит перед U в алфавите, поэтому он должен читать form_user .

Наконец, в вашей модели формы вы должны включить функцию ‘belongsToMany’:

 public function users() {
    return $this->belongsToMany('AppUser');
}
 

и в пользовательской модели вы бы включили то же самое в обратном порядке:

 public function forms() {
    return $this->belongsToMany('AppForm');
}
 

Если вы правильно ввели миграции, вам никогда не понадобится создавать сводную модель. Вы можете просто вызвать другие объекты через отношение, чтобы получить array. ie:

 $user->forms
$form->users
 

Комментарии:

1. моя модель пользователя выглядит так: класс User расширяет аутентифицируемый {…}, потому что он был сгенерирован Jetstream Livewire, это проблема?

2. Нет … класс User обычно расширяет Authenticatable . Если вы будете следовать соглашению об именах, которое я объяснил выше, вам не понадобится сводная модель.

3. это именно то, что я сделал, но у меня была ошибка, сообщающая мне, что у меня нет сводной таблицы с именем forms_user, когда моя миграция имела то же имя, но с символом «s» в конце

4. Сводная таблица в вашей миграции должна содержать два имени классов в алфавитном порядке с подчеркиванием между ними. Итак, да … поскольку вы назвали свой класс Forms как множественное число, то ваша сводная таблица в ваших миграциях должна быть forms_user .

5. ошибка: SQLSTATE[42S02]: Базовая таблица или представление не найдено: 1146 Таблица ‘MyDB.forms_user’ не существует (SQL: select users .*, forms_user . forms_id as pivot_forms_id , forms_user . user_id as pivot_user_id из users inner join forms_user on users . id = forms_user . user_id where forms_user . forms_id = 31 и users . deleted_at равно нулю) (Просмотр: /home/user/public_html/V8Form/resources/views/groupes/list.blade.php )

Ответ №2:

После долгой и кропотливой работы я, наконец, смог решить проблему, поэтому вместо сохранения данных через сводные модели я сделал это напрямую через запрос на миграцию.

В любом случае, спасибо за ваше участие. Проблема решена!