简体   繁体   中英

Laravel 5.7 - accessor on a user model to get a collection's relationship based on a few factors

I have Users that could be related to items by aa few factors and I want to create a getItemDatesAttribute accessor that gets all of a users relevant items and get those items' dates. There isn't a direct relationship between the user and the dates in this scenario. I can get the relevant items:

/**
 * Accessor to get a user's relevant item dates
 *
 * @return mixed
 */
public function getItemDatesAttribute()
{
    $itemDates = Item::where('assigned_user_id', $this->id)
                   ->orWhereIn('assigned_team_id', $this->teams->pluck('id'))
                   ->with('dates')
                   ->get();
    dd($itemDates); // All the bugs with their dates if they have them...

    $itemDates->filter(function ($item) {
        // Not sure how to return just the dates
    });
}

Then I'm not really sure how to return all of the dates for all relevant bugs. The Item model has the relationship on it:

public function dates()
{
    return $this->hasMany(ItemDate::class, 'item_id', 'id');
}

The end result should be a collection of dates that through the few above factors (and any others needed) would be related to a user. I know I can achieve this with some nested foreach's, but was wondering if there was a better laravel way:

$items = Item::all();

    foreach ($items as $item) {
        if ($item->isRelative && !empty($item->dates)) {
            foreach ($item->dates as $item) {
                $dates[] = $date;
            }
        }
    }
    return $dates;

The isRelative is an accessor on the Item that does the same thing as my where/whereIn was doing in the first query.

Ended up figuring this out quite cleanly:

$relativeItems = Item::relativeTo($this)->with('dates')->active()->get();
return $relativeItems->pluck('dates')->flatten();

The relativeTo() and active() methods are scopes on the Item model.

You can achieve this using a join and select something like this

Item::join('item_dates', 'item.id', '=', item_dates.item_id')
    ->where('assigned_user_id', $this->id)
     ->orWhereIn('assigned_team_id', $this->teams->pluck('id') )
    ->selectRaw('item.id, item_dates.*')
    ->get();

This does not use the relationship but does the same thing and will proform better with large amounts of data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM