How to select model function via eloquent relation - laravel?

Viewed 1334

In my project I have a list of clients orders. Each order has id_carrier field to find carrier name (like dhl, ups etc.). Problem is that I need to select carrier name using function getName() from model carrier.

So my query looks like:

public function loadOrders()
{
    $orders = Order::select('id', 'reference', 'created_at','total_value')->with(['carrier' => function($carrier){
        $carrier->getName();
    }])->paginate(20);

    return $orders;
}

Error message:

message: "Call to undefined method Illuminate\Database\Eloquent\Relations\HasOne::getName()"

Model order:

public function carrier()
    {
        return $this->hasOne('App\SupremeShop\Models\Carrier', 'id', 'id_carrier');
    }

Model Carrier

public function getName()
    {
            return $this->translation->where('id_lang', 1)->first()->name;

    }

So my query is returning results for ajax and it's used by datatable. So I pass json as finish result. There is no problem with selecting classic database field - problem is only when i need to use relation to obtain carrier names.

If i do something like foreaching order list and call $order->carrier->getName() i will get carrier name without problems. But in my query i use getName() in context of 20 paginated results and i not sure how to create correct sql query.

Each order has one carrier. Each carrier has multiple translations. GetName function returns default translation.

1 Answers

The problem is that getName() method is for Carrier model not for query builder, so you have to define a relation to access name with translation

// Carrier class
public function translationEng() // let think id_lang=1 is English
{
    return $this->translation()->where('id_lang', 1);
}

// in controller
public function loadOrders()
{
    $orders = Order::select('id', 'reference', 'created_at','total_value')->with(['carrier' => function($carrier){
        $carrier->with(['translationEng' => function($query){
            $query->select('name');
        }]);
    }])->paginate(20);

    return $orders;
}

// you can access the name this way
foreach($orders as $order)
{
    $carrierName = $order->carrier->translationEng->name;
}
Related