Delete data with regards Many to Many in Laravel

Asked

Viewed 1,055 times

0

I’m having a problem deleting associated data in Laravel. I have user tables, records and tags. modelo relacional

As you can see the table users connects with records, while a pivot table (registro_has_tags) connects the record tables and tags.

The problem occurs when I try to delete a user, since I also want to erase the data table records relating to that user, however, when I try to do this I get an error message because of the many association for many between tags and records.

I have no idea how I can fix this in Laravel

Definition of models:

User...

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

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

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

    public function registro()
    {
        return $this->hasMany(Registro::class); //User tem muitos registros
    }

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }

Records...

namespace App;

use Illuminate\Database\Eloquent\Model;

class Registro extends Model
{
    protected $fillable = [
        'user_id', 
        'descricao', 
        'data_vencimento', 
        'valor', 
        'tipo', 
        'status'
    ];

    public function user()
    {
        // Retorna a associação com base no objeto
        return $this->belongsTo(User::class); //Perternce ao objeto usuário
    }

    public function tags()
    {
        return $this->belongsToMany(Tag::class, 'registros_has_tags');
    }
}

Tags...

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    protected $fillable = [
        'nome',
        'descricao'
    ];

    public function registro()
    {
        return $this->belongsToMany(Registro::class, 'registros_has_tags');
    }

}

I tried to perform the operation by taking the user id

public function destroy($id)
    {
        try{

            $user = $this->user->findOrFail($id);
            $user->registro()->detach();
            $user->delete($id);

            return response()->json([
                'data'=> [
                    'msg'=> 'Usuário deletado com sucesso!'
                ]
            ], 200);

        }catch(\Exception $e){
            return response()->json(['erro: ' => $e->getMessage()], 401);
        }
    }

The api Migrations are:

users...

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

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

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

Records...

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

class CreateTableRegistros extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('registros', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('user_id');
            $table->text('descricao');
            $table->date('data_vencimento');
            $table->float('valor');
            $table->enum('tipo', ['D', 'C', 'P', 'R']); 
            $table->boolean('status')->nullable(true); //Campo pode ser nulo
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users');
        });
    }

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

Tags...

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

class CreateTableTags extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('nome');
            $table->string('descricao');
            $table->timestamps();
        });
    }

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

Pivot table(registres_has_tags)

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

class CreateTableRegistrosHasTags extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('registros_has_tags', function (Blueprint $table) {
            $table->unsignedBigInteger('registros_id');
            $table->unsignedBigInteger('tags_id');

            $table->foreign('registros_id')->references('id')->on('registros');
            $table->foreign('tags_id')->references('id')->on('tags');

        });
    }

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

    Ask the question the definitions of models and how he tried to make the exclusion.

  • Beauty Anderson. I just put the model settings.

  • Have you considered cascading exclusion in your Migrations?

  • I’ve actually tried yes. I don’t know if I used the deletion correctly, but it didn’t work

  • Put the Migrations please

  • Some notes, in the user model the registration method should be records (one for many), the detach() method applies to Many to Many which is the relationship that exists between records and tags and not to one to Many which is the type of relationship between user and records

  • Thanks for the tips Jorge, I will correct the error as soon as possible. Thanks also for the explanation on the detach()

Show 2 more comments

1 answer

1


Guys, I was able to solve the problem using onDelete('Cascade') in Migrations

was the following:

$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')

I appreciate all your help :)

  • That’s what I was gonna say

Browser other questions tagged

You are not signed in. Login or sign up in order to post.