简体   繁体   English

Laravel 5.2理解“胖模型,瘦控制器”

[英]Laravel 5.2 understanding “fat model, skinny controller”

I'm trying to understand how to use "fat model, skinny controller" in Laravel 5.2. 我试图了解如何在Laravel 5.2中使用“胖模型,瘦模控制器”。 Basically, I mostly understand the why, and the what, but not the how. 基本上,我大多理解为什么,以及什么,但不是如何。 I've been Googling for a while, and I have found several pages describing why (and some pages describing why not) and what, but no pages that makes it easy to understand how you create a fat model with skinny controllers. 我已经谷歌搜索了一段时间,我发现了几个页面描述了为什么(以及一些页面描述了为什么没有)和什么,但没有页面让你很容易理解如何使用瘦控制器创建胖模型。

I have created a extremely basic Todo-list, no login or validation, just the most basic todo-note functionality. 我创建了一个非常基本的Todo列表,没有登录或验证,只是最基本的todo-note功能。 This application basically uses "skinny model, fat controllers" and I want to rewrite the app so that it uses "fat model, skinny controllers" instead. 这个应用程序基本上使用“瘦模型,脂肪控制器”,我想重写应用程序,以便它使用“胖模型,瘦模控制器”。

I have three tables in the MySQL-database: 我在MySQL数据库中有三个表:

  • users 用户
    • id int(10) id int(10)
    • uname varchar(255) uname varchar(255)
    • email varchar(255) email varchar(255)
    • password varchar(60) 密码varchar(60)
  • projects 项目
    • id int(10) id int(10)
    • pname varchar(255) pname varchar(255)
  • notes 笔记
    • id int(10) id int(10)
    • user_id int(10) user_id int(10)
    • project_id int(10) project_id int(10)
    • content text 内容文本
    • time_created timestamp time_created时间戳
    • time_deadline timestamp time_deadline时间戳
    • completed tinyint(1) 完成tinyint(1)
    • removed tinyint(1) 删除tinyint(1)

When I created the migrations for the tables, I used $table->foreign('user_id')->references('id')->on('users'); 当我为表创建迁移时,我使用了$table->foreign('user_id')->references('id')->on('users'); and $table->foreign('project_id')->references('id')->on('projects'); $table->foreign('project_id')->references('id')->on('projects'); for the notes table migration. 用于notes表迁移。 For some reason it did not work, so in the database notes.user_id and notes.project_id are not foreign keys to users.id and projects.id , which was the idea from the beginning. 出于某种原因,它没有工作,所以在数据库notes.user_idnotes.project_id不是外键users.idprojects.id ,这是从一开始的想法。 I'm guessing that it doesn't really matter for my questions below, but if it does, someone please tell me so I can try to fix that. 我猜这对我下面的问题并不重要,但如果确实如此,有人请告诉我,以便我可以尝试解决这个问题。

I have the following models (doc blocks removed) 我有以下模型(删除了doc块)

app\\User.php: 应用程序\\ user.php的:

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    public function notes()
    {
        return $this->hasMany(Note::class);
    }
}

app\\Project.php: 应用程序\\ Project.php:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Project extends Model
{
    public function notes()
    {
        return $this->hasMany(Note::class);
    }
}

app\\Note.php: 应用程序\\ Note.php:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Note extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function project()
    {
        return $this->belongsTo(Project::class);
    }
}

I have the following controllers (doc blocks removed) 我有以下控制器(删除了doc块)

app\\Http\\Controllers\\UserController.php: 应用程序\\ HTTP \\控制器\\ UserController.php:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\User;
use Response;

class UserController extends Controller
{
    public function index()
    {
        try {
            $statusCode = 200;
            $users = User::orderBy('uname', 'asc')->get()->toArray();
            $response = [];

            foreach ($users as $user) {
                $this_row = array(
                    'id' => $user['id'],
                    'name' => $user['uname'],
                );

                $response[] = $this_row;
            }
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return Response::json($response, $statusCode);
        }
    }
}

app\\Http\\Controllers\\ProjectController.php: 应用程序\\ HTTP \\ \\控制器ProjectController.php:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Project;
use Response;

class ProjectController extends Controller
{
    public function index()
    {
        try {
            $statusCode = 200;
            $projects = Project::orderBy('pname', 'asc')->get()->toArray();
            $response = [];

            foreach ($projects as $project) {
                $this_row = array(
                    'id' => $project['id'],
                    'name' => $project['pname'],
                );

                $response[] = $this_row;
            }
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return Response::json($response, $statusCode);
        }
    }
}

app\\Http\\Controllers\\NoteController.php: 应用程序\\ HTTP \\控制器\\ NoteController.php:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Note;
use App\User;
use App\Project;
use Input;
use Response;
use Redirect;

class NoteController extends Controller
{
    public function index()
    {
        try {
            $statusCode = 200;
            $notes = Note::where('removed', 0)
                ->orderBy('time_created', 'asc')->get()->toArray();
            $response = [];

            foreach ($notes as $note) {
                $user = User::find($note['user_id']); // Username for note
                $project = Project::find($note['project_id']); // Project name

                $this_row = array(
                    'id' => $note['id'],
                    'user' => $user['uname'],
                    'project' => $project['pname'],
                    'content' => $note['content'],
                    'completed' => $note['completed'],
                    'created' => $note['time_created'],
                    'deadline' => $note['time_deadline']
                );

                $response[] = $this_row;
            }
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return Response::json($response, $statusCode);
        }
    }

    public function destroy(Request $request)
    {
        try {
            $statusCode = 200;

            $note = Note::find($request->id);
            $note->removed = 1;
            $note->save();
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return $statusCode;
        }        
    }

    public function edit($request) 
    {
        try {
            $statusCode = 200;

            $note = Note::find($request);

            $response = array(
                'id' => $note['id'],
                'content' => $note['content'],
                'completed' => $note['completed'],
                'deadline' => $note['time_deadline']
            );
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return Response::json($response, $statusCode);
        }
    }

    public function update(Request $request)
    {
        try {
            $statusCode = 200;

            $note = Note::find($request->id);

            $note->content = $request->content;
            $note->time_deadline = $request->deadline;

            if ($request->completed == "true") {
                $note->completed = 1;
            } else {
                $note->completed = 0;
            }

            $note->save();
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return $statusCode;
        }
    }

    public function store(Request $request)
    {
        try {
            $statusCode = 200;

            $note = new Note;

            $note->user_id = $request->user;
            $note->project_id = $request->project;
            $note->content = $request->content;
            $note->time_deadline = $request->deadline;

            $note->save();
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return $statusCode;
        }    
    }
}

Finally, this is my app/Http/routes.php (comments removed) 最后,这是我的app / Http / routes.php(已删除评论)

<?php

Route::get('/', function () {
    return view('index');
});

Route::get('/notes', 'NoteController@index');
Route::get('/notes/{id}', 'NoteController@edit');
Route::delete('/notes', 'NoteController@destroy');
Route::put('/notes', 'NoteController@store');
Route::post('/notes', 'NoteController@update');

Route::get('/projects', 'ProjectController@index');
Route::get('/users', 'UserController@index');

Route::group(['middleware' => ['web']], function () {
    //
});

The complete code can be found at my GitHub here . 完整的代码可以在我的GitHub上找到

I'm using Angular to receive the JSON sent by the controllers. 我正在使用Angular来接收控制器发送的JSON。 This works fine for my current page but as you can see, my controllers have a lot of logic, which I would like to move to the model. 这适用于我当前的页面,但正如您所看到的,我的控制器有很多逻辑,我想转移到模型。 I don't understand how I do this, so here's my questions: 我不明白我是怎么做的,所以这是我的问题:

  • Which additional files should I create? 我应该创建哪些附加文件?
  • Where should they be located? 它们应该放在哪里?
  • What do I need in those files except the logic that currently is in the controllers? 除了当前在控制器中的逻辑之外,我需要在这些文件中做什么?
  • How should I rewrite the controllers to handle the data from the models? 我应该如何重写控制器来处理模型中的数据?

Your skinny controller could be the following, which will do the same what you did: 你瘦的控制器可能是以下,这将做你所做的相同:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Project;

class ProjectController extends Controller
{
    public function index()
    {
        $projects = Project::orderBy('pname', 'asc')->get(['id', 'name']);
        return response()->make($projects);
    }
}

But as Fabio mentioned, if you want to go further, checkout repositories. 但正如法比奥提到的,如果你想进一步,那么结账仓库。 Here is a good article: https://bosnadev.com/2015/03/07/using-repository-pattern-in-laravel-5/ 这是一篇很好的文章: https//bosnadev.com/2015/03/07/using-repository-pattern-in-laravel-5/

In most cases I'm wrapping repositories into services to create the business logic. 在大多数情况下,我将存储库包装到服务中以创建业务逻辑。 Controllers just handle routing, and models only contains relations or mutators and accessors. 控制器只处理路由, 模型只包含关系或变更器和访问器。 But it could differ by development methods. 但它可能因开发方法而有所不同。

Also, don't make db queries in foreach loops, take the advantage of Eloquent with, forexample: 另外,不要在foreach循环中进行db查询,利用Eloquent,例如:

$notes = Note::where('removed', 0)
            ->with(['user', 'project'])
            ->orderBy('time_created', 'asc')->get();

And you can access, like this: 您可以访问,如下所示:

foreach($notes as $note)
{
    echo $note->user->uname;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM