user3164046
user3164046

Reputation: 1

Using with() and find() while limiting columns with find cancels relation data

I have the following code that displays different data depending on if you are the authenticated user looking at your own data or if you are looking at data from another user. The code works but in my opinion is very nasty.

public function showUserDetailed(Request $request, $username)
    {
    $key = strtolower($username).'-data-detailed';

    if(Auth::user()->usenrame === $username) {
        $key = $key .'-own';
    }

    if(Cache::has($key)) {
        if($request->wantsJson()) {
            return request()->json(Cache::get($key));
        } else {
            return view('user/detailed', ['user' => Cache::get($key)]);
        }
    } else {
        if(Auth::user()->username === $username) {
            $u = User::where('username', $username)->first();

            $user = new \stdClass();
            $user->username = $u->username;
            $user->email = $u->email;
            $user->address = $u->address;
            $user->city = $u->city;
            $user->state = $u->state;
            $user->zip = $u->zip;
            $user->phone = $u->phone;
            $user->follows = $u->follows;
            $user->ratings = $u->ratings;
            $user->location = $u->location;
        } else {
            $u = User::where('username', $username)->first(['username', 'city', 'state']);

            $user = new \stdClass();
            $user->username = $u->username;
            $user->city = $u->city;
            $user->state = $u->state;
            $user->follows = $u->follows;
            $user->ratings = $u->ratings;
        }

        Cache::put($key, $user);

        if($request->wantsJson()) {
            return response()->json($user);
        } else {
            return view('user/detailed', ['user' => $user]);
        }
    }
}

I have tried to use something similar to the following in the model calls.

User::where('username', $username)->with('follows', 'ratings', 'location')->find(['username', 'city', 'state');

However when I specify the columns to get from the user table it negates the relation data so it comes back as empty arrays. Is there a different way I can do this which would be cleaner? I despise having to create a stdClass to be a data container in this situation and feel I may be missing something.

// this works
User::where('username', $username)->with('follows', 'ratings', 'location')->first();

// this also works
User::where('username', $username)->first(['username', 'city', 'state']);

// this does not
User::where('username', $username)->with('follows', 'ratings', 'location')->first(['username', 'city', 'state']);

Upvotes: 0

Views: 46

Answers (1)

DevK
DevK

Reputation: 9942

When you specify columns and want to get the related models as well, you need to include id (or whatever foreign key you're using) in the selected columns.

The relationships execute another query like this:

SELECT 'stuff' FROM 'table' WHERE 'foreign_key' = ($parentsId)

So it needs to know the id of the parent (original model). Same logic applies to all relationships in a bit different forms.

Upvotes: 1

Related Questions