0

I have Category Model like below

class Category extends Model
{    
    public function users(){
        return $this->hasMany(User::class)->where("active_status",1)->where("user_type", 'user');
    }
}

I have User Model like below

class User extends Authenticatable
{
    public function getFullName()
    {
        return $this->first_name.' '.$this->middle_name.' '.$this->last_name;
    }
}

My controller code is like below

$category = Category::join('users', 'users.category_id', '=', 'categories.id')->get(); 

I am trying to use below code in view

@foreach( $result as $spc )

  $spc->getFullName();

@endforeach

I am getting error like below

[2019-09-24 14:45:43] laravel.ERROR: Call to undefined method App\Category::getFullName()
7
  • 3
    The error is pretty clear... $spc is a Category, not a User, and you've defined the function on your User class. Also, getFullName() should be getFullNameAttribute(), and calling $user->full_name will magically return the full name. See accessors: laravel.com/docs/5.8/eloquent-mutators#defining-an-accessor Commented Sep 24, 2019 at 14:49
  • 1
    Also you're not declaring any relation... If you follow the official guidelines will be much easier to retrieve the relation (Category::with('users')->get()) and show it in your view ($spc->user->getFullName()) Commented Sep 24, 2019 at 14:50
  • 1
    @TimLewis right... My mistake, didn't see it's a HasMany relation Commented Sep 24, 2019 at 15:05
  • 1
    @IlGala No worries :) I would definitely consider converting your comment to an answer; you've got the right approach and reasoning to solve this. Commented Sep 24, 2019 at 15:07
  • 2
    I'm answering also to another question so... I'll answer to this in a few! :) Commented Sep 24, 2019 at 15:08

1 Answer 1

3

Following the comments, the best way to achieve your goal is to use properly the Eloquent relationships

So in your controller change your query from

$category = Category::join('users', 'users.category_id', '=', 'categories.id')->get();

to

$categories = Category::with('users')->get();

Now the result will be a collection of Category with the users relation eagerly loaded, something like:

[
  {"id": 1, "name": "My category 1", "users": [{"id": 1, "mail": "[email protected]"}, {"id": 2, "mail": "[email protected]"}]},
  {"id": 2, "name": "My category 2", "users": []},
  {"id": 3, "name": "My category 3", "users": [{"id": 7, "mail": "[email protected]"}]},
]

in your view with a simple foreach you can iterate the categories and each user:

<table>
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Users</th>
        </tr>
    </thead>
    <tbody>
        @foreach($categories as $category)
        <tr>
            <td>
                {{ $category->id }}
            </td>
            <td>
                {{ $category->name }}
            </td>
            <td>
                <ul>
                    @foreach($category->users as $user)
                    <li>
                        {{ $user->getFullName()}}
                    </li>
                    @endforeach
                </ul>
            </td>
        </tr>
        @endforeach
    </tbody>
</table>

Side note

I saw that your relation is declared as

public function users(){
    return $this->hasMany(User::class)->where("active_status",1)->where("user_type", 'user');
}

I don't like very much to add all those where inside the relation declaration. I think it's a better approach using the local scopes since that code may be used in other parts of your code.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks @IIGala for you nice Answer. It is working. But I need to get {{ $category->name }} inside the loop (@foreach($category->users as $user)). How can I do that ? I have to print category_name with each user individually. Thanks.
@abuabu It's a nested loop, you have access to $category in that second foreach, so simply {{ $category->name }}
Thanks @TimLewis. But I am using like this. $result = array(); foreach($category as $cat) { foreach($cat->users()->orderBy('id', 'desc')->paginate(20) as $value) { $result[] = $value; } }foreach( $result as $spc ){ // some code here, I would like to get category_name here }
Why are you nesting so many foreach? It's a nonsense... anyway IMHO you should change the initialization of the result array... something like $result[] = ['category' => $cat->name, 'users' => $value]; and in the last loop you have both the attributes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.