Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SangminKim's avatar

saveMany refering to a wrong table

Hi there, I have three tables with relationships:

Event - id / title / etc...

Corporate - id / name / etc...

EventCorporate - id / event_id / corporate_id. ( the ID field might not be necessary but I'm keeping it for now )

And each model looks like the following:

class Event extends Model
{
    protected $fillable = [
        'title',
        ...
    ];

    public function corporates_attending_events(){
        return $this->hasMany(EventCorporate::class);
    }

    public function add_corporate( $corporate ){
        $method = ( $corporate instanceof Corporate ) ? 'save' : 'saveMany';
        $this->corporates_attending_events()->$method( $corporate );

    }

    // and more codes...
}


class Corporate extends Model
{
    protected $fillable = [
        'name',
        'description',
        'link',
        'thumbnail',
        'is_active'
    ];

    // and more codes...
}


class EventCorporate extends Model
{

    protected $table = 'event_corporate';

    protected $fillable = [
        'event_id',
        'corporate_id',
        'is_active'
    ];

    public function event(){
        return $this->hasOne(Event::class);
    }

    public function corporate(){
        return $this->hasOne(Corporate::class);
    }

    // and more codes...
}

When I run the following unit test for Event:

public function it_adds_a_coporate_to_the_event()
    {
        $event = create_an_event();
        $corporate = factory(Corporate::class)->create();
        $event->add_corporate($corporate);
        $this->assertEquals(1, $event->corporates_attending_events->count());
    }

The unit test fails with the following error message:

Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such column: event_id (SQL: update "corporates" set "event_id" = 1, "updated_at" = 2019-01-11 21:26:08 where "id" = 1)

The first thing I instantly noticed is that add_corporate(...) in Event motel is trying to update a wrong table - coporates. I thought corporates_attending_events() is pointing to event_corporate table due to the relationship created above... but it seems not.

Where is this thing coming from?

Did I set the relationships incorrectly?

The source code for save/saveMany is from Jeffrey's tutorial ( https://laracasts.com/series/phpunit-testing-in-laravel/episodes/6 ). For those who cannot access laracasts, the source files are here (https://github.com/laracasts/Hands-On-Testing-Workflow)

Thanks!

0 likes
5 replies
SangminKim's avatar

One more thing I noticed is... if I use create / createMany instead, it is pointing to a correct table :O

Using create / createMany can be a solution but I'd like to stick with save/saveMany if possible since I do not need to convert the attributes to arrays

Snapey's avatar

if a table has a column referring to another table then it should be belongs_to

SangminKim's avatar

@SNAPEY - Ahhhhh, I see.... that was my fault there...

public function corporates_attending_events(){
        return $this->belongsToMany(EventCorporate::class, 'event_corporate', 'event_id', 'id');
    }

    public function add_corporate( $corporate ){
        $method = ( $corporate instanceof Corporate ) ? 'save' : 'saveMany';
        $this->corporates_attending_events()->$method( $corporate );

    }

I've changed the codes like this and now it's displaying a different error message.

Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: event_corporate.corporate_id (SQL: insert into "event_corporate" ("event_id", "id") values (1, 1))

The corporate id is still not being passed... is it another relationship issue?

Thanks

Snapey's avatar
Snapey
Best Answer
Level 122

Check the docs for belongsToMany.

If you want to use EventCorporate to act as a pivot table between Event and Corporate then you need to reference the other model and not the EventCorporate model.

If you don't need to store data in this middle model then you can ignore it and use belongsToMany on either side. The convention would be to rename the table to corporate_event. You don't have to do this but if not then you need to mention the table name when declaring the relationship.

Please or to participate in this conversation.