Ad

How To Return A Model With His Relations In Laravel?

I have a ManyToMany relation with a pivot table. Between my model Deck and PlayCard how can I return my deck with his Playcard inside?

Something like this:

id: 1,
...
play_cards: [
    {
        id: 1, ...
    },
    {
        id: 2, ...
    }
]

I tried to use the with() function, but it doesn't work.

This is my function:

public function addToDeck(Request $request)
{
    $play_card = Auth::user()->playCards()->where('uid', $request->card_uid)->first();
    $deck = Auth::user()->decks()->where('token', $request->deck_token)->first();

    if (!$play_card || !$deck) {
        return ResponseService::respondWithErrors(
            400,
            $this->routes_messages[__FUNCTION__],
            ['Error Deck or Uid unknow.']
        );
    }

    if ($play_card->decks()->find($deck->id)) {
        return ResponseService::respondWithErrors(
            400,
            $this->routes_messages[__FUNCTION__],
            ['Card already in this deck.']
        );
    }

    $deck->playCards()->attach($play_card);
    $deck->save();

    return ResponseService::respondOK(
        200,
        $this->routes_messages[__FUNCTION__],
        $deck
    );
}
Ad

Answer

In the code you've shown, the $deck in the successful response won't show any related playcards because you never loaded the relationship on the deck. You accessed the relationship query to add the new playcard, but you never actually ran the query to get the playcards for the deck.

However, using with to load the initial playcards won't help you much either. Your response will include the original playcards, but it won't include the new one you just added. Modifying related records doesn't affect records that are already loaded.

In this instance, after you attach the new card to the deck's related cards, you will need to reload the relationship for the card to show up in the response.

// Add the card to the deck.
$deck->playCards()->attach($play_card);

// Load (or reload) the new set of related playcards. This will populate
// the $deck->playCards attribute so it will show up in your response.
$deck->load('playCards');

On a side note, there is no reason to save the $deck. You didn't modify anything on it. If you're attempting to update the updated_at timestamp on the deck, that still won't work, since it won't actually update any fields if the model isn't dirty. If that is your goal, however, you can use the touch() method ($deck->touch()).

Ad
source: stackoverflow.com
Ad