1
votes

I have a One to Many relationship between two classes. When I try to receive the belongsTo child via eager loading, it doesn't work for some odd reason. According to the following it should work: https://laravel.com/docs/master/eloquent-relationships#eager-loading

Te tables have the following columns, among others (legacy made, no option to change this). kasticket_.kassa_id and kassa.code refer to each other:

kasticket_.ticketnr, kasticket_.kassa_id, ...
kassa.code, ...

Here are the classes, somewhat simplified. ReceiptDetail:

<?php

namespace App;

use App\Pos;
use Illuminate\Database\Eloquent\Model;

class ReceiptDetail extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'kasticket_';

    /**
     * The primary key for the model.
     *
     * @var string
     */
    protected $primaryKey = 'ticketnr';

    /**
     * Get pos.
     */
    public function pos()
    {
        return $this->belongsTo(Pos::class, 'kassa_id', 'code');
    }
}

Pos:

<?php

namespace App;

use App\ReceiptDetail;
use Illuminate\Database\Eloquent\Model;

class Pos extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'kassa';

    /**
     * The primary key for the model.
     *
     * @var string
     */
    protected $primaryKey = 'code';

    /**
     * Get the receipt details.
     */
    public function receiptDetails()
    {
        return $this->hasMany(ReceiptDetail::class, 'kassa_id', 'code');
    }
}

This gives null as a result, rather than the Pos model. In the query log I can see it gets eager loaded however:

$receipts = \App\ReceiptDetail::with('pos')->get();
foreach ($receipts as $receipt) {
    dd($receipt->pos);
}

This gives me the expected Pos model, but an extra DB request has been made:

$receipts = \App\ReceiptDetail::with('pos')->get();
foreach ($receipts as $receipt) {
    dd($receipt->pos()->first());
}

From the query log I see the following:

select * from `kasticket`
select * from `kassa` where `kassa`.`code` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2
ReceiptDetail has one pos() record right?DsRaj
ReceiptDetail table must have pos_id according to how you've setup this relation. Instead of dd use dump and see the result for all $receipts you are selecting. Maybe the first one really has pos_id as null.d3jn
@DsRaj, that is correctRuben Colpaert
@RubenColpaert add the table schema in your questionDsRaj
I added some information. Working with legacy tables, which makes it kinda ugly, but this should help I think.Ruben Colpaert

2 Answers

0
votes

The unique identifiers of the tables (kasticket_.kassa_id and kassa.code) are strings in the DB. I had to add the following line the the Pos class:

/**
 * Indicates if the IDs are auto-incrementing.
 *
 * @var bool
 */
public $incrementing = false;
-1
votes

If you don't follow the proper name in primary key and foreign key then you need to add the relationship properly

Change like this:

public function pos()
{
   return $this->belongsTo(Pos::class,'foreign_key', 'local_key');
}

POS Model

public function receiptDetails()
{
   return $this->hasMany(ReceiptDetail::class,'foreign_key', 'local_key');
}

More info