skip to Main Content

Request for How to Handling if Command in Relationship Handling

Hello, good day Artisan,
Please, I need help with an if command not working for a relationship. I want to get the correct relationship for hashCard, but only the default relationship works. The if statement is not checking the status field of the UserHashCard model, which uses an enum ('available', 'initiated', 'joined', 'completed').

UserHashCard Model Code

<?php
namespace AppModels;

use IlluminateDatabaseEloquentModel;

class UserHashCard extends Model {
    protected $guarded = [];

    public function hashCard() {
        return $this->belongsTo(HashCard::class);
    }

    // Uncomment if needed
    // public function exchanges()
    // {
    //     return $this->hasMany(HashCardExchange::class, 'hash_card_id');
    // }

    public function initiatedExchanges()
    {
        return $this->hasMany(HashCardExchange::class, 'hash_card_id', 'hash_card_id');
    }

    public function joinedExchanges()
    {
        return $this->hasMany(HashCardExchange::class, 'hash_card_id', 'join_card_id');
    }

    public function exchanges()
    {
        if ($this->status == 'initiated') {
            return $this->initiatedExchanges();
        } elseif ($this->status == 'joined') {
            return $this->joinedExchanges();
        }

        // Default relationship (e.g., for 'available' or other statuses)
        return $this->initiatedExchanges();
    }
}

Controller Code
php
Copy code
public function getHashCards() {
    $user = User::find(Auth::user()->id);

    $hashCards = $this->allCards($user->id);

    return response()->json($hashCards);
}

private function allCards($userid)
{
    $user = User::find($userid);

    // Fetch UserHashCards with their exchanges and associated usernames
    $hashCards = UserHashCard::query()
        ->where('user_id', $user->id)
        ->with([
            'hashCard', // Existing relationship
            'exchanges' => function ($query) {
                $query->with(['user:id,username']); // Eager load only the `id` and `username` fields from `users`
            }
        ])
        ->orderByRaw("
            CASE 
                WHEN status = 'initiated' THEN 1
                WHEN status = 'joined' THEN 2
                ELSE 3
            END
        ")
        ->get();

    return $hashCards;
}

2

Answers


  1. Chosen as BEST ANSWER

    @Hefer thank alot, i was able to make it work by modifying the allCards method in controller like this

       private function allCards($userid)
       {
           $user = User::find($userid);
       
           // Fetch UserHashCards with their exchanges and associated usernames
           $userHashCards = UserHashCard::query()
               ->where('user_id', $user->id)
               ->with([
                   'hashCard', // Existing relationship
                   'initiatedExchanges' => function ($query) {
                       $query->with(['user:id,username']); // Eager load only the `id` and `username` fields from `users`
                   },
                   'joinedExchanges'  => function ($query) {
                       $query->with(['user:id,username']); // Eager load only the `id` and `username` fields from `users`
                   }
               ])
               ->orderByRaw("
                   CASE 
                       WHEN status = 'initiated' THEN 1
                       WHEN status = 'joined' THEN 2
                       ELSE 3
                   END
               ")
               ->get();
       
               // Dynamically map exchanges based on card status and remove extra fields
               $userHashCards->transform(function ($card) {
                   $card->exchanges = match ($card->status) {
                       'initiated' => $card->initiatedExchanges,
                       'joined' => $card->joinedExchanges,
                       default => collect(),
                   };
           
                   // Remove initiated_exchanges and joined_exchanges fields
                   unset($card->initiatedExchanges, $card->joinedExchanges);
           
                   return $card;
               });
           
         return $userHashCards;
       }
    

  2. I was facing almost the same problem some time ago. I wanted to fetch users with active orders, and this is how it worked:

    public function getUsersWithActiveOrders() {
    $users = User::with('orders')->get();
    $users->transform(function ($user) {
        $user->active_orders = $user->orders->filter(function ($order) {
            return in_array($order->status, ['pending', 'shipped']);
        });
        return $user;
    });
    return response()->json($users);
    }
    

    In your case, I think you are not using the relationship you defined. Here is how it should be:

    public function conditionalExchanges() {
        if ($this->status == 'initiated') {
            return $this->initiatedExchanges;
        } elseif ($this->status == 'joined') {
            return $this->joinedExchanges;
        }
        return collect();
    }
    

    Now in your controller, call the realtionship:

    public function getHashCards() {
    $user = User::find(Auth::user()->id);
    $hashCards = $this->allCards($user->id);
    
    $hashCards->each(function ($hashCard) {
        $hashCard->conditional_exchanges = $hashCard->conditionalExchanges();
    });
    
    return response()->json($hashCards);
    }
    

    and for the allCards function:

    $hashCards = UserHashCard::query()
        ->where('user_id', $user->id)
        ->with('hashCard')
        ->orderByRaw("
            CASE 
                WHEN status = 'initiated' THEN 1
                WHEN status = 'joined' THEN 2
                ELSE 3
            END
        ")
        ->get();
    

    Let me know, if there is a problem after this.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search