5

I'm using laravel resources to get data for api:

        return [
            'id' => $this->id,
            'unread' => $this->unread,
            'contact' => UserResource::collection($this->users),
        ];    

And this is working fine. The problem is when 'users' is empty. I mean - not every time my controller is loading users from my relations:

    $offers = Offer::where('user_id', $user_id)->orderBy('created_at','desc')->get();
    foreach ($offers as $offer)
    {
        $offer->setRelation('users', $offer->users->unique());
    }
    return OfferShortResource::collection($offers);

sometimes - this relation does not exists. But not the relation is problem, because - my resource is not loading the relation - the relatin is loaded inside controller.

So how can I add some kind of logic to resources? - to tell basically - users property may not exists - then do not load data here, or even - do not check $this->users relation

edit: I tried to make it like this:

 use Illuminate\Support\Arr;
 ...

      'contact' => $this->when(Arr::exists($this, 'users'), function () {
                    return UserResource::collection($this->users);
                }),

but this is giving always false

edit 2: relation in the Offer model

 public function users(){
        return $this->belongsToMany(User::class, 'messages', 'offer_id', 'from')
       ->where('users.id', '!=', auth()->user()->id);
5
  • Laravel Docs - Eloquent - API Resources - Conditional Relationships whenLoaded Commented Jul 4, 2018 at 19:57
  • I tried this, giving error: "message": "Class 'App\\Post' not found", "exception": "Symfony\\Component\\Debug\\Exception\\FatalThrowableError", "file": "C:\\www2\\medpraca2\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Concerns\\HasRelationships.php", Commented Jul 4, 2018 at 20:00
  • lol, no, my code is like: 'contact' => UserResource::collection($this->whenLoaded('users')), Commented Jul 4, 2018 at 20:02
  • then that error obviously has nothing to do with what you have shown here, so not sure what you want anyone to do for you Commented Jul 4, 2018 at 20:03
  • trust me, when I comment this line there is no error, and my relation is working well inside controller Commented Jul 4, 2018 at 20:05

1 Answer 1

11

Try using whereHas:

Offer::whereHas('users', function ($query) use ($user_id) {
    $query->where('user_id', $user_id);
})->orderByDesc('created_at')->get();

The optional helper is useful for accessing properties that may not be defined:

optional($this->user)->name

The when method should work for you, try the following:

'contact' => $this->when(property_exists($this, 'users'), function () {
    return UserResource::collection($this->users);
}),

Also try:

isset($this->users)
Sign up to request clarification or add additional context in comments.

7 Comments

It is a logic for controller, in controller everything works fine, I want to add logic to api Resource to conditionally add 'contact' value
checking again for today and property_exists($this, 'users') isn't working inside resources, gives me always false, even if I would put it other value like property_exists($this, 'unread') etc
Can you include the full code for OfferShortResource?
no, but I've tried now isset($this->users) and it works with it, you may update the answer and I'll accept again
anyway it's strange that property_exists is not working inside api resources
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.