John Evans Solachuk
John Evans Solachuk

Reputation: 2105

Laravel : How do I get records from pivot table whereby its foreign key does not reference a primary key?

I have 2 tables linked by belongsToMany relationship and a pivot table and it's working fine. Then I tried referencing a non-primary key instead of a primary key in the pivot table. However when I run my code in my controller, laravel does not return any result.

I guess it might be because in a belongsToMany relationship, laravel automatically thinks the foreign keys in pivot tables are referencing to the primary keys and that's why my code doesn't work.

How do I change laravel's logic?

p.s. I'm able to get those records by using ConversationsUser model but it accesses the database twice in order to get the results (it checks the conversation table first then checks the pivot table). That would be my last resort if I can't find other solutions.


CONTROLLER

$loginuser = User::find(Auth::user()->id);
$conversations = $loginuser->conversations;
dd($conversations->toArray());

It returns an empty array when there are actually valid records in the pivot table. I need it to return those records.

MODELS

User

public function conversations(){
   return $this->belongsToMany('Conversations')->withPivot('opened','last_seen');
}

Conversations note:as you can see, I have tried adding 2 more parameters as suggested in this answer but still doesn't work.

public function users(){
    return $this->belongsToMany('User','conversations','conversations_id');
}

MIGRATIONS

User

Schema::create('users',function($table)
        {
            $table->increments('id');
            $table->string('email')->unique();
            $table->string('password',100);
            $table->string('name',150);
            $table->string('usertype',50);
            $table->boolean('block');
            $table->string('remember_token',100);
            $table->timestamp('lastlogin_at');
            $table->timestamps();
            $table->softDeletes();
        });

Conversations

        Schema::create('Conversations', function(Blueprint $table)
        {
            $table->increments('id');
            $table->bigInteger('conversations_id')->unsigned()->index();
            $table->string('name',100);
            $table->timestamps();
            $table->bigInteger('microseconds');
        });

conversations_user

        Schema::create('conversations_user', function(Blueprint $table)
        {
            $table->increments('id')->unsigned();
            $table->bigInteger('conversations_id')->unsigned()->index();
            $table->foreign('conversations_id')->references('conversations_id')->on('conversations')->onDelete('cascade');
            $table->integer('user_id')->unsigned()->index();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->timestamps();
            $table->bigInteger('microseconds');
            $table->boolean('opened');
            $table->dateTime('last_seen');
        });

Upvotes: 0

Views: 2302

Answers (1)

wiramaswara
wiramaswara

Reputation: 69

Try change from this

public function users(){
    return $this->belongsToMany('User','conversations','conversations_id');
}

to this

public function users(){
    return $this->belongsToMany('User','conversations_user','user_id','conversations_id');
}

The second argument of belongsToMany is table name of your junction table according to [0]

[0] http://laravel.com/api/class-Illuminate.Database.Eloquent.Relations.BelongsToMany.html.

Also because you use different key for Conversations table, try to change it in your Conversation model by adding this two variable inside your model class :

class Conversation extends Eloquent {
    protected $primaryKey = "conversation_id";
    public $incrementing = false; 

Upvotes: 1

Related Questions