Question

Programs has Items and Uitems table ( there can be many programs and many programs can have same or different items whereas items can be in different programs)

pivot table : has items_id and items_type where items_id can have 'id' from either items or uitems

so if i were to list Programs::find(1)->with('Items', 'uItems') where if items_type ===user use uitems else use items i need something like this!

I have Programs table:

id  user_id name    description 
1   2   x workouti  High intensity
2   1   yn workouti low intensity
3   2   c workouti  massive workout
4   2   b oldm abi  sfsdf

I have a pivot table seen in picture below. The structure of my pivot table

Programs table has a relation with 2 tables below

  1. items "core" --> id | category_id | name | description
  2. Uitems "user" --> id | user_id | name | description

If you look at the pivot table i have two columns named items_id and items_type those two represent items and uitems table SO;

if(items_type === 'user') then pull info from Uitems as well as;
if(items_type === 'core') then pull info from items.

What i have tried was to;

Route::get('ws/{id?}', function($id)
{    
    $workouts = array('Monday'=>'', 'Tuesday'=>'', 'Wednesday'=>'', 'Thursday'=>'', 'Friday'=>'', 'Saturday'=>'', 'Sunday'=>'');
    $days = Days::all()->lists("name", "id");
        foreach($days as $dayKey => $day)
        {
            foreach($programs = Programs::find($id)->items()->wherePivot('days_id', $dayKey)->orderBy('sorts_id', 'ASC')->get() as $prokey => $program)
            {
                $program->settings = Settings::find($program->pivot->settings_id)->toArray();

                if($program->pivot->items_type ==='core')
                {
                   $program->items = Items::find($program->pivot->items_id)->toArray();
                }else if ($program->pivot->items_type ==='user')
                {
                   $program->items = Uitems::find($program->pivot->items_id)->toArray();
                   $program->by    =User::find(Uitems::find($program->pivot->items_id)->user_id)->toArray();
                }
                $workouts[$day][] = $program->toArray();
            }
        }


        $program = json_encode($workouts);
        return $program;

});

But this code results in 39 query attemps to the mysql which is not cool at all. Which provides me exactly what i want with a weak performance:

enter image description here

Where is says by:oguzhan Piskin has the info from Uitems whereas others from Items

I need to accomplish this using Eloquent's Eager loading. Also query builder is find but my priority is on eager loading with Eloquent. Any help or clue highly appriciated!

Programs model:

class Programs extends Eloquent

{ protected $table = "programs";

public function items()
{
    return $this->belongsToMany('Items')->withPivot('settings_id', 'days_id', 'sorts_id', 'id', 'items_type', 'items_id');
}

since i reach data using programs i was only using items to reach the data but when uitems data joins the challange in the pivot table i cant use both.

Was it helpful?

Solution

Try something like : Read more here about eager loading constrains

Edit your model :

public function items() 
{ 
return $this->belongsToMany('Items')->wherePivot('items_type', 'core')->withPivot('settings_id', 'days_id', 'sorts_id', 'id', 'items_type', 'items_id') 
}
public function uitems() 
{ 
return $this->belongsToMany('Items')->wherePivot('items_type', 'users')->withPivot('settings_id', 'days_id', 'sorts_id', 'id', 'items_type', 'items_id') 
}

And in your controller :

    <?php
    Route::get('ws/{id?}', function($id)
    {    
        $workouts = array('Monday'=>'', 'Tuesday'=>'', 'Wednesday'=>'', 'Thursday'=>'', 'Friday'=>'', 'Saturday'=>'', 'Sunday'=>'');
        $days = Days::all()->lists("name", "id");
        $program = Programs::find($id)->with('items','items');
?>

Hope i understood correctly what you wanted. Please let me know

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top