Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Megatech's avatar

Retrieving data from 3 different tables

Hello, good day guys. Please i am trying to retrieve loggedin users data from differient tables (When a user login their information should be what is displayed to them in their dashboard), my code only get data from one table correctly but the others just bring out any data of the first user in the table not the Authenticated user's data. Here is my code, i think i am missing something.

public function dashboard() {
    $data['data'] = auth()->user();
    $data['set'] = Setting::get()->where(auth()->user());
    $data['card'] = Card::get()->where(auth()->user());
    return view('user/dashboard', $data);
}

Please help as i am still new to mastering laravel. Thanks

0 likes
23 replies
automica's avatar

make some relationships between User -> Setting and User -> Card.

<?php

class User {

    public function card()
    {
        return $this->hasOne(Card::class);
    }

    public function settings()
    {
        return $this->hasMany(Setting::class);
    }

}
?>

and then you can do:

<?php

public function dashboard()
{
    $data = [
        'settings' => auth()->user()->settings,
        'card' => auth()->user()->card
    ];
    return view('user/dashboard', $data);
}

no need to pass auth into blade as you can access it directly as auth()

Megatech's avatar

@automica you said "no need to pass auth into blade as you can access it directly as auth()" how do i do this because i just followed your method and i'm getting this error

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'settings.user_id' in 'where clause' (SQL: select * from `settings` where `settings`.`user_id` = 3 and `settings`.`user_id` is not null)
automica's avatar

@Megatech how are you associating settings and user?

if user hasMany settings, you'd put the user_id on the settings table.

lets see a schema please

Megatech's avatar

@automica please disregard how i am retrieving the Settings, it is not associated with the users. This is how i am actually using the setting in my main file.

    $user = auth()->user();
    $settings = Setting::get();
    $card = Card::where('user_id', $user->id)->first(); 
    return view('user.dashboard', compact('user', 'settings', 'card'));

here is my setting schema

Schema::create('settings', function (Blueprint $table) {
            $table->id();
            $table->text('site_desc')->nullable();
            $table->string('tawk_id')->nullable();
            $table->string('email')->nullable();
            $table->string('mobile')->nullable();
            $table->text('address')->nullable();
            $table->string('gradient1')->nullable();
            $table->string('gradient2')->nullable();
            $table->integer('email_notify')->nullable();
            $table->integer('sms_notify')->nullable();
            $table->integer('kyc')->nullable();
            $table->integer('email_verification')->nullable();
            $table->integer('sms_verification')->nullable();
            $table->integer('registration')->nullable();
            $table->timestamps();
        });

the setting just only control how the dashboard operate, for example the registration table check the status of the registration if the app accept new registration or not, something like that.

Now i'm trying to retrieve data as an array so that i don't pass too many variable in the return view like this

    return view('user.dashboard', compact('data')); //everything should be inside the data

i tried this but did not work

$user = auth()->user();
$data['setting'] = Setting::get();
$data['card'] = Card::where('user_id', $user->id)->first();
return view('user/dashboard', compact($user, $data));

I think the problem is from the last line, the blade view is not receiving the data

kokoshneta's avatar

There are two fundamental things very wrong with your queries:

  1. ->get() fetches the rows from the database, creates an Eloquent Collection object with those rows and returns that collection. That means everything you do after ->get() is not part of the query and never goes to the database – it’s instead a function used to filter the collection. Any database function calls need to come before ->get().
  2. ->where() (both for database queries and collection filtering) requires at least two arguments: one to specify which column you’re filtering by, and one to specify which value that column should have. ->where($user) is equivalent to writing in SQL WHERE $user, which will evaluate $user as a boolean value and return either all rows or no rows.

Also, auth()->user() returns an object for the current user. In quite a few places in Laravel, you can pass an object and Laravel will know to use the primary key in that object, but it’s generally better practice not to rely on that, because it doesn’t work everywhere. For instance, it doesn’t work in the ->where() function in collections.

So, Setting::get()->where(auth()->user()) does this:

  • Retrieves all records from the settings table as a collection
  • Filters that collection by a column named… whatever the string value of a user object is (basically “Filter the collection and only return elements where [Object]”, which makes no sense)

What you want to do is filter in the database (by putting where() before get()), and of course tell the database what column you’re trying to filter on as well (by using both parameters to the where() function). Since you say (further below) that there’s only ever one row per user, you also don’t want to retrieve a whole collection of objects – you just need a single model instance, so use first() instead of get():

$user = auth()->user();
$settings = Setting::where('user_id', $user->id)->first();
$cards = Card::where('user_id', $user->id)->first();
return view('user/dashboard', compact('user', 'settings', 'cards'));
Megatech's avatar

@kokoshneta @kokoshneta i used your method and i'm getting

Property [mastercard] does not exist on this collection instance.

it seems like it is not getting anything from the table, meanwhile here is my card schema

 Schema::create('cards', function (Blueprint $table) {
            $table->id();
            $table->integer('user_id')->nullable();
            $table->string('mastercard')->nullable();
            $table->string('mas_cvv')->nullable();
            $table->string('mas_exp')->nullable();
            $table->string('visacard')->nullable();
            $table->string('visa_cvv')->nullable();
            $table->string('visa_exp')->nullable();
            $table->timestamps();
        });

here is how i am using it in my view file

<div class="middle">
          <h1> {{$cards->mastercard}}</h1>
          <img src="{{asset('images/card chip.png')}}" class="chip">
       </div>
kokoshneta's avatar

@Megatech In your Blade view, you try to access $cards->mastercard directly.

That won’t work if you use get(), because (as I said in my first answer), get() returns a collection of objects. The collection has no property called mastercard, that property belongs to the individual objects in the collection.

Are you certain that there will only ever be one row per user in both the cards and settings table? If so, you can simply replace get() with first(), which returns a single model instance instead of a collection.

If there may be more than one row, you should loop through the collection:

@foreach ($cards as $card)
	<div class="middle">
		<h1> {{$card->mastercard}}</h1>
		<img src="{{ asset('images/card chip.png') }}" class="chip">
	</div>
@endforeach

Also, and even more importantly:

NEVER STORE USERS’ PAYMENT CARD DETAILS IN YOUR DATABASE!!!

It’s almost certainly not legal, and you run the very real risk of having hundreds or thousands of customers’ card details stolen and abused, with you liable for the leak.

kokoshneta's avatar

@Megatech All right, then it should work if you just replace get() with first() (I’ve updated the original answer). And if it’s not real card data, you’re fine.

Megatech's avatar

@kokoshneta can you also correct the return view because yours is throwing an error, the blade file is not receiving the datas, then i can mark it as best answer. thanks

return view('user.dashboard', compact('user', 'settings', 'cards'));

using this works fine.

Megatech's avatar

@kokoshneta also is there a way to shorten the return view, for example if i want to retrieve from "settings", "users", "categories", "card", instaed of retrieving them individually like we did, we just put them in an array so that when passing it into the view blade it receives just one variable of arrays like this

return view('user.dashboard', compact( 'data')); 

everything collected should be in just one variable. because there might me cases whereby i want to retrieve data from like 10 tables, passing 10 variables in the return view is somehow.

kokoshneta's avatar
Level 27

@Megatech Sure, you can do that. You would then use $data['user'], etc., in the Blade template.

Alternatively, if you make sure that your array is associative and your array keys are the same as the variable names you use in your Blade template, you can just pass $data directly and then keep using $user, $setting, $card and so on in your template as you’ve been doing:

// Controller
$data['user'] = $user = auth()->user();
$data['setting'] = Setting::where('user_id', $user->id)->first();
$data['card'] = Card::where('user_id', $user->id)->first();
return view('user/dashboard', $data);
// Blade template
<div class="middle">
	<h1>{{ $card->mastercard }}</h1>
	<img src="{{ asset('images/card chip.png') }}" class="chip">
</div>
Megatech's avatar

@kokoshneta exactly i tried this same thing but the "$user->id" is showing red underlined. when i hover, it says "undefined variable $user"

$data['setting'] = Setting::where('user_id', $user->id)->first();
$data['card'] = Card::where('user_id', $user->id)->first();
kokoshneta's avatar

@Megatech Oh yeah, forgot to change that. Obviously if you’re not saving the user in a variable named $user, it won’t be available for use in the other queries. You can either just use auth()->user() three times or use a temporary variable $user (as in the updated comment).

Megatech's avatar

@kokoshneta do you mean something like this

$user = auth()->user();
$data['setting'] = Setting::where('user_id', $user->id)->first();
$data['card'] = Card::where('user_id', $user->id)->first();
return view('user/dashboard', extract($user, $data));

If yes, the "extract" method in the return view will be expecting an Int in the second variable, changing the extract to compac the view is not recieving the data

kokoshneta's avatar

[[ This comment relates to an earlier version of the accepted answer. It is no longer relevant. ]]

@Megatech No, you can’t use extract() like that; the second argument to that is a flag, not an array. The updated comment above has it as it should be: compact('data') in the controller creates an array of the structure ['data' => $data]; this is passed to the view() function, and the value of each array element (there is only one) is made available to the view as a variable named from the corresponding array key; then that’s extracted into separate variables within the view.

In other words, at the start of the Blade template, the view’s symbol table will contain this:

$data = [
	'user' => (model instance of class User),
	'setting' => (model instance of class Setting),
	'card' => (model instance of class Card)
];

When you extract() that, it creates a variable in the view’s symbol table for each of the array keys, so the symbol table will then look like this:

// $data is still there
$data = [
	'user' => (model instance of class User),
	'setting' => (model instance of class Setting),
	'card' => (model instance of class Card)
];

// but so are these three
$user = (model instance of class User);
$setting = (model instance of class Setting);
$card = (model instance of class Card);
Megatech's avatar

@kokoshneta Thanks, i think i missed your updated comment before, now it is working. I really appreciate your support.

kokoshneta's avatar

@Megatech I just randomly thought of this post and realised that the compacting and extracting is completely stupid and unnecessary: $data is already an associative array, which is what the view() function expects the data parameter to be, so you can just pass it directly, as-is.

I’ve updated the accepted answer accordingly.

CODE-AXION's avatar

try to use ->first() method instead of ->get()

like this:

$card = Card::where('user_id', $user->id)->first(); //here you use the ->first() method
return view('user/dashboard')->with('card',$card);

and the in the view you can do it like this:


{{$card->mastercard}}

1 like

Please or to participate in this conversation.