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

zakiaziz's avatar

In a many-to-many polymorphic relationship how do I set the "primary" key in the *ables table?

Due to privacy concerns I'm changing the names of my table but it goes something like this:

posts
    id - integer
    name - string

videos
    id - integer
    name - string

twowords
    id - integer
    name - string

twowordable
    twoword_id - integer
    twowordable_id - integer
    twowordable_type - string

I'm trying to save a relationship between a post and a twoword like this:

$post = App\Post::find(5);
$post->twowords()->attach($twowords_id);

And the error I get is:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'two_word_id' in 'field list' (SQL: insert into `twowordables` (`two_word_id`, `twowordable_id`, `twowordable_type`) values (59, 59, App\Tenant))

Where does laravel find the column name two_word_id? I want the column name to be twoword_id

0 likes
4 replies
michaeldyrynda's avatar

You can pass the key name as the third parameter of the morphMany method, although, it's easiest to just stick to the default conventions unless you have a good reason otherwise.

The column name is derived from the eloquent model; which is why the conventions are in place.

1 like
zakiaziz's avatar

In my post.php model file I have this:

    public function twowords()
    {
        return $this->morphToMany('App\TwoWords', 'twowordable', 'twoword_id');
    } 

But still getting the same error

michaeldyrynda's avatar
Level 41

@zakiaziz now that I'm on a computer and not my phone, the method signature of morphToMany is as follows:

public function morphToMany($related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)

If you take a look at Illuminate\Database\Eloquent\Model::morphToMany, you can see how this relationship is built up and why it expects a certain convention:

$table is derived as the plural of $name - twordables $foreignKey is derived as $name.'_id- twordable_id $otherKey is derived from (new $name)->getForeignKey(), which is the snake-cased class name with _id appended - two_word_id

So in your instance, you would (I'm pretty sure) need something along the following lines:

public function twowords()
{
    return $this->morphToMany(
        // the related model
        'App\TwoWords',
    
        // the relationship name
        'twowordable',
    
        // the table name, which would otherwise be derived from the relationship name - twowordables
        'twordable',

        // the foreign key will be twowordable_id, derived from the relationship name, which you're adhering to
        null,

        // the 'other' key, which would otherwise be derived from the related model's snake case name - two_word_id
        'twoword_id'
    );
}
4 likes
iatrodev's avatar

Thank you for your reply! Exactly what i've been looking for

Please or to participate in this conversation.