首页 文章

Laravel最佳实践 - 查询

提问于
浏览
0

我需要将一些数据传递给我的视图 . 我有两个模型用户和提示模型 .

User模型有一个返回用户hasMany(Tip :: Class)的方法,Tip模型有一个返回tipTo(User :: class)的方法 .

我正在为用户创建一个配置文件页面,并使用路由模型绑定在访问配置文件时返回用户模型 .

public function tipsterProfileShow(User $tipster)
{
  if (!$tipster->isTipster())
  {
    return redirect()->route('home');
  }

  return view('profile.index')->with([
    'tipster' => $tipster,
    'tips' => $tipster->tips(),
  ]);
}

我想显示一些数据,例如提示表中状态列指示的正确提示数量 .

目前我正在使用刀片视图

{{$tips->where('status','Won')->count()}}

我觉得这不是最好的做法,但我可能错了 .

做下面这样的事情会更好吗?

public function tipsterProfileShow(User $tipster)
{
  if (!$tipster->isTipster())
  {
    return redirect()->route('home');
  }
  return view('profile.index')->with([
    'tipster' => $tipster,
    'tips' => $tipster->tips(),
    'wins' => $tipster->tips()->where('status', 'Won')->count()
  ]);
}

这样我就会将查询保留在视图之外 . 我真的很喜欢laravel和'最佳实践'所以试图得到一些建议 .

3 回答

  • 1

    你问的是最好的练习,这通常是不赞成的,但这确实是每个初学者应该学习的必备内容,所以我仍然认为这是值得回答的 .

    简而言之:是的!你正在做的是保持代码被逻辑分开的第一步 . 您的视图应负责显示数据,您的控制器应负责处理数据到视图 . 您的控制器是否应该实际负责计算数据是另一个主题,也是一个经常争论的话题 .

    也就是说,如果你应用一些其他逻辑,你可以将它归结为控制器中的一行:

    public function tipsterProfileShow(User $tipster)
    {
      return view('profile.index', compact('tipster'));
    }
    

    第一步是在 User 模型中添加一个方法,如下所示:

    public function winCount()
    {
        return $this->tips()->where('status', 'Won')->count();
    }
    

    现在,您可以从视图中访问 $tipster->winCount() . 您也可以在视图中直接访问 $tipster->tips() - 大多数人都同意这完全没问题 .

    第二步是将非tipters的重定向调用提取到中间件中,您可以在这里阅读:https://laravel.com/docs/5.3/middleware

    您可以从那里采取进一步的步骤,但这是一个很好的起点 . 祝好运! :)

  • 0

    我会建议你创建一个 POPO (Plain Old PHP Object) ,它将包含一个用户简档与用户配置文件同义的完整描述 .

    laravel中的模型表示表中的一行,它将延迟加载与其相关的任何关系 .

    因此,如果您有 POPO ,您将能够定义与用户相关的所有内容并将其传递给视图,而无需在视图中进行查询 .

    以下面为例:

    Class UserPorfile{
      private $id;
      private $username;
      private $tips;
    
      public function setId($id){
         $this->id = $id;
      }
    
      public function getId(){
         return $this->id;
      }
    
      public function setUsername($username){
          $this->username = $username;
      }
    
      public function getUsername(){
         return $this->username;
      }
    
      public function setTips(array $tips){
         $this->tips = $tips;
      }
    
      public function getTips(){
         return $this->tips;
      }
    }
    

    将此类对象传递给您的视图似乎要好得多

  • 0

    是的,你是对的 . 鉴于您正在尝试遵循MVC软件开发模式,您应该避免在您的视图中放置业务逻辑 .

    这行代码:

    {{$tips->where('status','Won')->count()}}
    

    实际上做了两件事:

    • 使用特定条件查询所有对象的模型

    • 计算结果

    通过遵循MVC原则,它应该是您的控制器将命令发送到模型,而不是视图 .

    祝好运!

相关问题