2

I am currently working with laravel 4 I am trying to retrieve collection with constraint but it doesn't work as expected

model Caracteristique :

public function valeur() {

    return $this->hasMany('Valeur','id_caracteristique','id');

}

model valeur

public function caracteristique() {

    return $this->belongsTo('Caracteristique','id','id_caracteristique');

}

public function produit() {

    return $this->belongsToMany('Produit','produit_valeur');

}

model categorie

public function produit() {

    return $this->belongsToMany('Produit','produit_categorie');
}

model produit

public function valeur() {

    return $this->belongsToMany('Valeur','produit_valeur');
}

I want :

Caracteristique, with values where categorie = x through produit

final goal : To be able parsing collection like

caracteristique->valeur;

in SQL

SELECT c.id,v.id FROM caracteristique c
INNER JOIN valeur v on (v.id_caracteristique = c.id)
INNER JOIN produit_valeur pv on (pv.valeur_id = v.id)
INNER JOIN produit_categorie pc on (pc.produit_id = pv.produit_id)
GROUP by c.id

When i use join in eloquent relationship no longer available

I have tried this :

$carac = Caracteristique::with(array('valeur.produit.categorie' => function($q) {

$q->whereCategorieId(2);

 }))->get();

But the constraint not respected ..

Any ideas ?

Regards,

find this bad solution ...

$values = Valeur::whereHas('produit',function($q) {
$q->whereHas('categorie',function($q) {
    $q->where('categorie.id','=',2);

});
})->lists('id');

$carac = Caracteristique::with(array('valeur' =>function ($q) use($values) {
$q->wherein('id',$values);

}))->get();

Someone with best practice ?

lwillems
  • 103
  • 13

1 Answers1

1

If you want limit Caracteristique:

$catId = 2;

Caracteristique::whereHas('valeur', function ($q) use ($catId) {
  $q->whereHas('produit', function ($q) use ($catId) {
    $q->whereHas('categorie', function ($q) use ($catId) {
      $q->where('cateogorie.id', $catId);
    });
  });
})->get();

or if you want to load all Caracteristique and limit related Valeur only:

Caracteristique::with(['valeur' => function ($q) use ($catId) {
  $q->whereHas('produit', function ($q) use ($catId) {
    $q->whereHas('categorie', function ($q) use ($catId) {
      $q->where('cateogorie.id', $catId);
    });
  });
}])->get();

As you can see this is not the best piece of code to use, so instead simply use joins.

Jarek Tkaczyk
  • 78,987
  • 25
  • 159
  • 157
  • Hi, thx for reply, Very surprised That laravel does not provide best solution for nested contraint, query is awful !! – lwillems Aug 29 '14 at 19:25
  • The query itself is not that awful, but the code you need to do it is. There's PR of mine to make it easier, but Taylor hasn't merged it yet https://github.com/laravel/framework/pull/4954 – Jarek Tkaczyk Aug 29 '14 at 21:05
  • I have used laravel native relationship to build a basic, product, categories, attributes system. You think it's wrong way to do ? – lwillems Aug 30 '14 at 04:42
  • Eloquent is just great for basic stuff and quick setup. However when the application requires complex logic, then I go with repository and custom methods, and finally if it needs further improvements, often replace Eloquent with Doctrine, which works a bit defferently. That being said, I wouldn't say it's wrong way, but in future you may find it not enough for yuour needs. – Jarek Tkaczyk Aug 30 '14 at 08:09
  • Ok i understood, the first query given not filtering with categorieID, returns all data of caracteristique/valeur very strange ... – lwillems Aug 30 '14 at 15:29
  • I don't understand what you mean. – Jarek Tkaczyk Aug 30 '14 at 16:53
  • the first query without with('valeur') not filltering on categorieID wherehas, returning all caracteristique with all values. – lwillems Aug 30 '14 at 21:42