在 Laravel 中,我们必须在哪里编写查询:在模型、控制器或路由中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34449446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:52:53  来源:igfitidea点击:

Where do we have to write queries in Laravel: in model, controller or routes?

phplaravellaravel-5ormeloquent

提问by anoop Singh

I'm little confused with the database queries in the laravel, where do we have to write our queries: in controllers, models or routes ?

我对 Laravel 中的数据库查询有点困惑,我们必须在哪里编写查询:在控制器、模型或路由中?

I've been through many tutorials and I see so much difference. Just creating confusion.

我已经学习了很多教程,我看到了很多不同之处。只会制造混乱。

Kindly explain somebody

请解释一下

回答by Moppo

It depends on different factors, but in short you can write them both in Model, Controllers or Repositories

这取决于不同的因素,但简而言之,您可以在模型、控制器或存储库中编写它们

If you're writing a controller action and you need a query that you'll use only once, it's perfectly fine to write the query directly in the controller(or even in the route's closure ).

如果您正在编写一个控制器操作并且您需要一个只使用一次的查询,那么直接在控制器中(甚至在路由的闭包中)编写查询是非常好的。

For example, if you want to get all users of type admin:

例如,如果您想获取所有类型为 的用户admin

$admins = User::where('type', 'admin')->get();

Now, suppose you need to get the admins in more than one controller method; instead of rewriting the same query, you can create a Repository class to wrap the access to the users' Model and write the query inside the Repository:

现在,假设您需要在多个控制器方法中获取管理员;您可以创建一个 Repository 类来包装对用户模型的访问,并在 Repository 中编写查询,而不是重写相同的查询:

class UserRepository
{
    public function getAllAdmins()
    {
        return User::where('type', 'admin')->get();
    }
}

Now in you controllers you can inject the Repository and use the same method of the Repository to get the admin users: this will keep you code DRY as you don't have to repeat the same query among the controllers' actions

现在在您的控制器中,您可以注入存储库并使用存储库的相同方法来获取管理员用户:这将使您保持代码干燥,因为您不必在控制器的操作中重复相同的查询

Controller

控制器

public function __construct(UserRepository $userRepo)
{
     $this->userRepo = $userRepo;
} 

//controller action
public function index()
{
     $admins = $this->userRepo->getAllAdmins(); 
}

Finally, let's suppose you need a query to count the number of the admin users. You could write this query in the UserRepository:

最后,假设您需要一个查询来计算管理员用户的数量。您可以在以下位置编写此查询UserRepository

public function getAdminNum()
{
    return User::where('type', 'admin')->count();    
}

And it would be ok, but we can note that the User::where('type', 'admin')fragment of the query is shared with the query in getAllAdminsSo we can improve this by using query scopes:

没关系,但我们可以注意到User::where('type', 'admin')查询的片段与 中的查询共享getAllAdmins所以我们可以通过使用查询范围来改进这一点:

User Model

用户模型

public function scopeAdmins($query)
{
    return $query->where('type', 'admin');    
}

by this, in the UserRepositorymethods we can rewrite our previous queries as:

这样,在UserRepository方法中,我们可以将之前的查询重写为:

public function getAllAdmins()
{
    return User::admins()->get();
} 

public function getAdminNum()
{
    return User::admins()->count();  
}

And i've just showed you a case in which a query would be writed inside a Model

我刚刚向您展示了一个在模型中写入查询的案例

回答by Chaudhry Waqas

You do not write any query in Model. Modelis just for mapping the class that you are going to use for a table like User Model will be mapped to users (plural of model name).

您不在Model. Model仅用于映射您将用于表的类,例如 User Model 将映射到用户(模型名称的复数)。

You do not write queries in the routes closures like this

您不会像这样在路由闭包中编写查询

Route::get('/', ['as' => 'home', function(){
    $totalProblems = Problem::count();

    $solvedProblems = Problem::where('solved', 1)->get()->count();

    $unsolvedProblems = Problem::where('solved', 0)->get()->count();

    return view('Pages.index', ['totalProblems' => $totalProblems, 'solvedProblems' => $solvedProblems, 'unsolvedProblems' => $unsolvedProblems]);
}]);

This is considered as bad practice, its just for testing purposes.

这被认为是不好的做法,仅用于测试目的。

You always write your queries in the controller method associated with your route like this

您总是在与您的路线关联的控制器方法中编写您的查询,如下所示

Route::get('test', 'HomeController@test');

and in your HomeController

并且在你的 HomeController

<?php namespace App\Http\Controllers;
use App\Problem;

    class HomeController extends Controller {

        public function test(){
            $user = User::all();
            return view('Pages.test')->withUser($user); //or

            return view('Pages.test')->with('user' , $user);
        }
    }