首页 > 解决方案 > 使用模型功能

问题描述

我有Category如下模型

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

我有User如下模型

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

我的控制器代码如下

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

我正在尝试使用下面的代码view

@foreach( $result as $spc )

  $spc->getFullName();

@endforeach

我收到如下错误

[2019-09-24 14:45:43] laravel.ERROR: Call to undefined method App\Category::getFullName()

标签: laravel

解决方案


根据评论,实现目标的最佳方法是正确使用Eloquent 关系

所以在你的控制器中改变你的查询

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

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

现在结果将是关系急切加载的集合,例如Categoryusers

[
  {"id": 1, "name": "My category 1", "users": [{"id": 1, "mail": "user1@example.com"}, {"id": 2, "mail": "user2@example.com"}]},
  {"id": 2, "name": "My category 2", "users": []},
  {"id": 3, "name": "My category 3", "users": [{"id": 7, "mail": "user7@example.com"}]},
]

在您的视图中,foreach您可以简单地迭代类别和每个用户:

<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>

边注

我看到你的关系被声明为

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

我不太喜欢where在关系声明中添加所有这些内容。我认为使用本地范围是一种更好的方法,因为该代码可能会在代码的其他部分中使用。


推荐阅读