thebigk's avatar
Level 13

Fetch user data when you have user ID

I seem to be stuck at a very basic problem. I need to create a news blog as an extension of my website which already has a user's table. I decided to create a new table called news_authors.

| id | user_id | state | role | created_at | updated_at

The user_id field references the id field on users table.

My question is, when i'm fetching data for authors in my blade template, I can do so by

$authors = Authors::all();

This fetches me the entries in the news_authors table. However, I now need to show pick up user_id from the fetched result and get corresponding data from users table. My best bet is to run a foreach loop on $authors.

I'm wondering if there's a better way to address this. I tried defining a 'news_authors' belongs to 'users' relationship; but that doesn't look right.

What's the right way to fetch relevant user data in this situation?

0 likes
9 replies
xmarks's avatar

On your Authors Model:

public function user() {
    return $this->hasOne(User::class);
}

On your Controller, change what you had above to:

$authors = Authors::with('user')->get();

You can now get your user data with:

$author->user->email; // and so on any other data
thebigk's avatar
Level 13

@xmarks - thank you for quick response. I've this in my AuthorController now:

public function index() {
        $authors = Authors::with('user')->all();
        return view('AdminPanel.news.authors',compact('authors'));
    }

and Author Model has:

class Authors extends Model {
    protected $table = 'news_authors';
    protected $fillable = ['user_id', 'state', 'role'];

    public function user() {
        return $this->hasOne(User::class);
    }
}

Blade however throws error Call to undefined method Illuminate\Database\Query\Builder::all()

silverxjohn's avatar

I think it should be get() instead of all()

$authors = Authors::with('user')->get();
xmarks's avatar

sry, my bad. It seems you can not call all() after with(). Change it to:

$authors = Authors::with('user')->get();

tested it, and this is working properly.

thebigk's avatar
Level 13

No luck with get(). It's now throwing

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.authors_id' in 'where clause' (SQL: select * from `users` where `users`.`authors_id` in (1, 2, 3, 4, 5))
silverxjohn's avatar

Can you post your database structure?

The error tells us that your users table doesn't have a column named authors_id

Can you confirm that these tables and column do exists and that there's no typo?

xmarks's avatar
xmarks
Best Answer
Level 8

That is happening because your Model name Author does not follow the convention rules, where your should have a table named authors instead you have a table named news_authors.

You should either have a Model named NewsAuthor (note, not NewsAuthors), or you will have to change all methods to include the correct table fields as such:

return $this->hasOne('App\Phone', 'foreign_key', 'local_key');

So something like this should work for you:

public function user() {
    return $this->hasOne(User::class, 'id', 'user_id');
}

Also, on your Author Model, you should have this to define your Table Name:

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'news_authors';

And this should do it

thebigk's avatar
Level 13

Here's how it is: https://ibb.co/b8Nih6

users table:

id | name | email | password | role | remember_token | created_at | updated_at

news_authors table

id | user_id | state | role | created_at | updated_at

user_id on news_authors references id on users table.

thebigk's avatar
Level 13

@xmarks - What a great way to learn about foreign key and local key and defining relationships ! Won't forget this, ever!

Defining the local key and foreign key did the trick! :-D

Please or to participate in this conversation.