Search code examples
laraveleloquentmodelrelation

Alternative relationship in the same Laravel relation


In my model, i created this relationship...

public function traduzione(): HasOne
    {
        $check = $this->hasOne(Linguaofferte::class,'id_offerta')->where('tradattiva','=',1)->where('lingua','=',$this->currentLang )->first();
        if(empty($check)){
            return $this->hasOne(Linguaofferte::class,'id_offerta')->where('lingua','=', config()->get('warp.default_platform_language') );
        }else{
            return $this->hasOne(Linguaofferte::class,'id_offerta')->where('lingua','=',$this->currentLang );
        }
    }

In the relation, an initial check if the offer translation in the chosen language exists. If the translation doesn't exist, then it get the translation in the default language.

If i execute the query with the 'with' method, e.g. Offerta::where(...condition..)->with('traduzione')->first() the check in the relation is not considered and always takes the last return.

If instead i get the translation after the query, it works, e.g.

$offer = Offerta::where(..condition..)->first();
$translation = $offer->traduzione;

How is that? Is there a possibility of creating an alternative relationship in the same relation? Suggestions welcome!


Solution

  • You can try with nested default models

    the code below is not tested but you can get the idea

    public function traduzione(): HasOne
    {
        return $this->hasOne(Linguaofferte::class, 'id_offerta')
            ->where('tradattiva', '=', 1)
            ->where('lingua', '=', $this->currentLang)
            ->withDefault(function (Linguaofferte $linguaofferte, Offerta $offferta) {
                return $linguaofferte
                    ->where('id_offerta', '=', $offferta->id)
                    ->where('lingua', '=', config()->get('warp.default_platform_language'))
                    ->first();
            })
            ->withDefault(function (Linguaofferte $linguaofferte, Offerta $offferta) {
                return $linguaofferte
                    ->where('id_offerta', '=', $offferta->id)
                    ->where('lingua', '=', $this->currentLang)
                    ->first();
            });
    }