Pergunta

I'm not sure this is a real relation. I will try to explain the best way I can.

So first of all, I have three models : Appartement, AppartementPrice

The AppartementPrice depends on : - appartement_id

I would like the AppartementPrice to be retrieve like that :

If there is a specific price for the appartement, then retrieve it, If not retrieve the price for all appartement which is stored in the database with an appartement_id = 0.

So basically what I would like is to do something like that :

    public function price()
    {
        if(isset($this->hasOne('AppartementPrice')->price) // Check that relation exists
            return $this->hasOne('AppartementPrice');
        else
            return $this->hasOne('AppartementPrice')->where('appartement_id', '0');
    }

But this is not working. It does not retrive me the default price. I guess anyway this is not a best practice ? I first tried to get the informations like that :

//Check if appartment has a specific price or retrieve default
if($priceAppartement = AppartementPrice::getPriceByCompanyAppartement($this->id))
    return $priceAppartement;
else
    return AppartementPrice::getDefaultPrice();

But I had this error : Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation when doing :

 echo $app->price->price;

How can I check that a relation exists ? And is there a way to do as I describe ?

Thank you

Foi útil?

Solução

You can't replace relation like this, as what you intend is not logical - you want to retrieve relation that doesn't exist.

Instead you can do this:

public function getPriceAttribute()
{
    return ($this->priceRelation) ?: $this->priceDefault();
}

public function priceDefault()
{
    // edit: let's cache this one so you don't call the query everytime
    // you want the price
    return AppartmentPrice::remember(5)->find(0);
}

public function priceRelation()
{
    return $this->hasOne('AppartementPrice');
}

Then you achieve what you wanted:

$app->price; // returns AppartmentPrice object related or default one

HOWEVER mind that you won't be able to work on the relation like normally:

$price = new AppartmentPrice([...]);
$app->price()->save($price); // will not work, instead use:
$app->priceRelation()->save($price);

Outras dicas

First of all something really important in Laravel 4.

When you do not use parentheses when querying relationship it means you want to retreive a Collention of your Model. You have to use parentheses if you want to continue your query.

Ex:

// for getting prices collection (if not hasOne). (look like AppartementPrice)
$appartment->price;

// for getting the query which will ask the DB to get all
//price attached to this appartment, and then you can continue querying
$priceQuery = $appartment->price();

// Or you can chain your query
$appartment->price()->where('price', '>', 0)->get() // or first() or count();

Secondly, your question.

//Appartement Model

// This function is needed to keep querying the DB
public function price()
{
    return $this->hasOne('AppartementPrice')
}

// This one is for getting the appartment price, like you want to
public function getAppartmentPrice()
{
   $price_object = $this->price;
   if (!$price_object) // Appartment does not have any price {
      return AppartementPrice->where('appartement_id', '=', 0)->get();
   }
   return $price_object;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top