八、微薄CRUD

八、微薄CRUD

一、学习目标

我们将在本章开始进行微博功能的开发,让用户可以在网站上发布微博,删除微博。下一章我们还将加入用户的关注功能,用户可以在首页上看到自己关注的人发布的微博动态。

二、微博模型

接下来让我们跟之前一样,先创建一个分支:

$ git checkout master
$ git checkout -b user-statuses

1、基本模型

首先我们要先为微博创建一个数据表来储存微博数据,一条简单的微博至少需要拥有微博内容(content)和微博发布者(user_id)的信息。接下来让我们创建一个新的迁移文件来创建微博数据表。

$ php artisan make:migration create_statuses_table --create="statuses"

这里我们把微博的表名设为 statuses,意为『动态』。

打开新创建的微博迁移文件并加入以下内容。

database/migrations/[timestamp]_create_statuses_table.php

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateStatusesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('statuses', function (Blueprint $table) {
            $table->increments('id');
            $table->text('content');
            $table->integer('user_id')->index();
            $table->index(['created_at']);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('statuses');
    }
}

接下来让我们对新增的几个重要字段进行详细讲解。

第一个字段为 text 类型的 content 字段,将用于储存微博的内容。

$table->text('content');

第二个字段为 integer 类型的 user_id 字段,用于储存微博发布者的个人 id,后面我们会借助 user_id 来查找指定用户发布过的所有微博,因此为了提高查询效率,这里我们需要为该字段加上索引。

$table->integer('user_id')->index();

第三个则是为微博的创建时间添加索引,由于 timestamps 方法会为微博数据表生成一个微博创建时间字段 created_at 和一个微博更新时间字段 updated_at,因此在这里我们并不需要再手动创建。为微博的创建时间添加索引的目的是,后面我们会根据微博的创建时间进行倒序输出,并在页面上进行显示,使新建的微博能够排在比较靠前的位置。

$table->index(['created_at']);

在我们定义好迁移文件之后,运行以下命令来执行迁移。

$ php artisan migrate

接着,我们还需要创建微博模型来跟数据库进行交互,创建的命令很简单。但请记住,所有我们新建的模型文件都要统一放置在 app/Models 文件夹下,为此我们在创建一个新的模型对象时,需要在模型名称前面加上 Models 目录。

$ php artisan make:model Models/Status

2、用户和微博之间的关联

前面我们讲过,在创建微博的时候,该微博必须拥有一个发布者,而该发布者可以拥有多条微博,则便是 数据模型关联中经常谈到的一对多关系。

如果没有一对多的关系,我们需要这样来创建一条微博。

App\Models\Status::create()

当我们将用户模型与微博模型进行一对多关联之后,我们得到了以下方法。

$user->statuses()->create()

这样在微博进行创建时便会自动关联与微博用户之间的关系,非常方便。

Eloquent 模型让关联的管理和处理变得更加简单,同时也支持以下几种类型的关联:

  • 一对一

  • 一对多

  • 多对多

  • 远层一对多

  • 多态关联

  • 多态多对多关联

我们先从「一对多」来学习模型对应关系,下一章在构建用户粉丝关系的时候,我们会学习到「多对多」关联。我们可在模型中将 Eloquent 关联定义为函数,如下,我们可在微博模型中,指明一条微博属于一个用户。

app/Models/Status.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

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

在用户模型中,指明一个用户拥有多条微博。

app/Models/User.php

public function statuses()
{
    return $this->hasMany(Status::class);
}

需要注意的一点是,由于一个用户拥有多条微博,因此在用户模型中我们使用了微博动态的复数形式 statuses 来作为定义的函数名。

Git 代码版本控制

接着让我们将本次更改纳入版本控制中:

$ git add -A
$ git commit -m "微博数据模型"

三、显示微博

本节我们将为用户个人页面添加微博展示列表,用于显示该用户发布过的所有微博动态。

1、获取微博

首先我们需要在用户控制器的 show 动作中取出该用户发布过的所有微博。由于我们之前进行了模型关联,因此取出一个用户的所有微博可以通过以下方式:

$statuses = $user->statuses();

在我们将用户的所有微博取出之后,还需要根据微博的创建时间 created_at 对微博进行排序,让新创建的微博靠前显示。我们使用 Eloquent 模型提供的 orderBy 方法,通过指定字段名和排序方式来对微博进行排序。

$statuses = $user->statuses()->orderBy('created_at', 'desc');

desc 是英文 descending 的简写,意为倒序,也就是数字大的排靠前。

最后,由于用户的微博发布数量可能会非常多,因此我们对取出的微博数据进行分页,在每个页面最多只显示 30 条微博:

$statuses = $user->statuses()->orderBy('created_at', 'desc')->paginate(30);

现在,相信你已经知道如何为用户控制器的 show 动作添加微博动态的读取逻辑了。不过我们还是需要来看下具体实现代码。

app/Http/Controllers/UsersController.php

public function show(User $user)
{
    $statuses = $user->statuses()->orderBy('created_at','desc')->paginate(10);
    return view('users.show',compact('user','statuses'));
}

compact 方法可以同时接收多个参数,在上面代码我们将用户数据 $user 和微博动态数据 $statuses 同时传递给用户个人页面的视图上。

2、渲染微博

接下来我们来构建单条微博的局部视图,该局部视图最终将应用在用户的个人页面上。

微博的局部视图包含一条微博动态的发布者,发布内容以及发布日期等信息。其基本页面结构如下:

resources/views/statuses/_status.blade.php

<li class="media mt-4 mb-4">
    <a href="{{route('users.show',$user->id)}}">
        <img src="{{$user->gravatar()}}" alt="{{$user->name}}" class="mr-3 gravatar"/>
    </a>
    <div class="media-body">
        <h5 class="mt-0 mb-1">{{$user->name}} <small> / {{$status->created_at->diffForHumans()}}</small></h5>
        {{$status->content}}
    </div>
</li>

$status 实例代表的是单条微博的数据,$user 实例代表的是该微博发布者的数据。另外你可能还会注意到下面这个方法:

$status->created_at->diffForHumans()

该方法的作用是将日期进行友好化处理,我们可以使用 tinker 来查看该方法的具体输出情况。

$ php artisan tinker

在 tinker 中输出第一位用户的创建时间如下。

>>> $created_at = App\Models\User::first()->created_at
=> Carbon\Carbon {#704
     +"date": "1998-12-06 03:15:31.000000",
     +"timezone_type": 3,
     +"timezone": "UTC",
   }

在 tinker 中调用 diffForHumans 方法来输出,结果如下。

>>> $created_at->diffForHumans()
=> "17 years ago"

我们发现 diffForHumans 为我们生成的时间是英文的,如果要使用中文时间,则需要对 Carbon 进行本地化设置。Carbon 是 PHP DateTime 的一个简单扩展,Laravel 将其默认集成到了框架中。对 Carbon 进行本地化的设置很简单,只在 AppServiceProvider 中调用 Carbon 的 setLocale 方法即可,AppServiceProvider 是框架的核心,在 Laravel 启动时,会最先加载该文件。

app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

use Carbon\Carbon;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Carbon::setLocale('zh');
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
        if ($this->app->environment() !== 'production') {
            $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
        }
    }
}

现在,让我们重启 tinker:

$ php artisan tinker

可以看到输出的日期将变成中文。

>>> $created_at = App\Models\User::first()->created_at
>>> $created_at->diffForHumans()
=> "17年前"

现在,我们可以在用户的个人页面使用该局部视图和渲染微博的分页链接了。

resources/views/users/show.blade.php

@extends('layouts.default')
@section('title',$user->name)

@section('content')
    <div class="row">
        <div class="offset-md-2 col-md-8">
            <section class="user_info">
                @include('shared._user_info',['user'=>$user])
            </section>
            <section class="status">
                @if($statuses->count() > 0)
                    <ul class="list-unstyled">
                        @foreach($statuses as $status)
                            @include('statuses._status')
                        @endforeach
                    </ul>
                    <div class="mt-5">
                        {!! $statuses->render() !!}
                    </div>
                @else
                    <p>没有数据!</p>
                @endif
            </section>
        </div>
    </div>
@stop

在个人页面视图中,我们使用了 $statuses->count() 方法来判断当前页面是否存在微博动态,如果不存在则不对微博的局部视图和分页链接进行渲染:

image.png

3、示例微博

现在我们的用户还没有办法发布任何微博,因为我们的微博发布表单还未构建,但通过前面章节的学习,我们知道可以使用 Laravel 提供的数据填充功能来为应用生成测试数据。

首先我们需要为「微博模型」定义好用来生成的假数据的「模型工厂」。我们可以利用 Laravel 命令 make:factory 来生成工厂类文件:

$ php artisan make:factory StatusFactory

内容填入:

database/factories/StatusFactory.php

<?php

use Faker\Generator as Faker;

$factory->define(Model::class, function (Faker $faker) {
    $date_time = $faker->date . ' ' . $faker->time;
    return [
        'content' =>$faker->text(),
        'created_at'=>$date_time,
        'updated_at'=>$date_time
    ];
});

接着创建一个 StatusesTableSeeder 文件来对微博假数据进行批量生成。

$ php artisan make:seeder StatusesTableSeeder

我们不需要为每个用户都生成大量微博,为了测试方便且提高假数据的生成速度,我们只为前三个用户生成共 100 条微博假数据。

database/seeds/StatusesTableSeeder.php

<?php

use Illuminate\Database\Seeder;
use App\Models\Status;

class StatusesTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $user_ids = ['1','2','3'];
        $faker = app(Faker\Generator::class);

        $statuses = factory(Status::class)->times(100)->make()->each(function ($status) use ($faker,$user_ids){
            $status->user_id = $faker->randomElement($user_ids);
        });

        Status::query()->insert($statuses->toArray());
    }
}

我们通过 app() 方法来获取一个 Faker 容器 的实例,并借助 randomElement 方法来取出用户 id 数组中的任意一个元素并赋值给微博的 user_id,使得每个用户都拥有不同数量的微博。

接下来我们需要在 DatabaseSeeder 类中指定调用微博数据填充文件。

database/seeds/DatabaseSeeder.php

<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        Model::unguard();

        $this->call(UsersTableSeeder::class);
        $this->call(StatusesTableSeeder::class);

        Model::reguard();
    }
}

最后让我们对数据库进行重置和填充。

$ php artisan migrate:refresh --seed

现在任意访问前三个用户的个人页面,可以看到微博数据已成功生成:

image.png


Git 代码版本控制

接着让我们将本次更改纳入版本控制中:

$ git add -A
$ git commit -m "用户微博列表"

四、发布微博

1、微博相关操作

现在微博列表已能够正常展示,接下来让我们来完成微博的创建和删除操作。

如果使用 resource 方法来定义微博路由,则会生成完整的符合 RESTful 架构的路由,但我们完成微博的创建和删除只需要两个动作,因此我们可以对 resource 传参 only 键指定只生成某几个动作的路由。

routes/web.php

Route::resource('statuses','StatusesController',['only'=>['store','destroy']]);

该路由列表信息如下所示:

HTTP 请求URL动作作用
POST/statusesStatusesController@store处理创建微博的请求
DELETE/statusesStatusesController@destroy处理删除微博的请求

2、访问限制

在路由定义完成之后,我们需要生成一个微博动态控制器来处理微博的创建和删除操作。

$ php artisan make:controller StatusesController

由前面开发用户相关功能的经验可知,一些需要用户登录之后才能执行的请求需要通过中间件来过滤,接下来我们需要开发的 store 和 destroy 动作将用于对微博的创建和删除,这两个动作都需要用户登录,因此让我们借助 Auth 中间件来为这两个动作添加过滤请求。

app/Http/Controllers/StatusesController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class StatusesController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }
}

3、创建微博

下面我们开始来完善创建微博的动作,首先我们要对微博的内容进行限制,一条微博的最长长度为 140 个字符,且内容不能为空,通过前面学习的知识,我们知道其验证规则将如下所示:

'content' => 'required|max:140'

当我们在创建微博的时候,需要通过以下方式来进行创建。这样创建的微博会自动与用户进行关联。

$user->statuses()->create();

因为创建微博的用户始终为当前用户,借助 Laravel 提供的 Auth::user() 方法我们可以获取到当前用户实例。在创建微博的时候,我们需要对微博的内容进行赋值,因此最终的创建方法如下:

Auth::user()->statuses()->create([
    'content' => $request['content']
]);

由于我们接下来会在主页上同时显示微博发布表单和微博动态,因此在用户完成微博的创建之后,需要将其导向至上一次发出请求的页面,即网站主页,因此我们可以使用 back 方法来完成:

app/Http/Controllers/StatusesController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Auth;

class StatusesController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function store(Request $request)
    {
        $this->validate($request,[
            'content' => 'required|max:140'
        ]);

        Auth::user()->statuses()->create([
            'content'=>$request['content']
        ]);
        session()->flash('success','发布成功');
        return redirect()->back();
    }
}

接下来让我们在主页上创建一个微博发布表单,让用户可以发布微博。对于微博表单我们还需要单独抽离成一个局部视图出来,保证代码的可维护性。

微博表单的页面结构如下所示:

resources/views/shared/_status_form.blade.php

<form action="{{route('statuses.store')}}" method="POST">
    @include('shared._errors')
    {{csrf_field()}}
    <textarea name="content" id="" cols="30" rows="3" placeholder="聊聊新鲜事">{{ old('content') }}</textarea>
    <div class="text-right">
        <button type="submit" class="btn btn-primary mt-3">发布</button>
    </div>
</form>


为主页添加微博表单和当前用户个人信息。

resources/views/static_pages/home.blade.php

image.png

如果我们现在尝试发布一条微博,则会发现有如下报错:


image.png

Add [content] to fillable property to allow mass assignment on [App\Models\Status].

我们看到其中的关键信息 MassAssignmentException - 批量赋值异常,这是因为我们未在微博模型中定义 fillable属性,来指定在微博模型中可以进行正常更新的字段,Laravel 在尝试保护。解决的办法很简单,在微博模型的 fillable 属性中允许更新微博的 content 字段即可。

app/Models/Status.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Status extends Model
{
    protected $fillable = ['content'];

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


}

在尝试发布

image.png

image.png

下一节我们将会把发布的微博列表出来。

Git 代码版本控制

接着让我们将本次更改纳入版本控制中:

$ git add -A
$ git commit -m "发布微博"

五、首页微博列表

1、动态流原型

现在网站主页已经拥有微博的发布表单和当前登录用户的个人信息展示了,接下来让我们接着完善该页面,在微博发布表单下面增加一个局部视图用于展示微博列表。在开始之前,我们需要在用户模型中定义一个 feed 方法,该方法将当前用户发布过的所有微博从数据库中取出,并根据创建时间来倒序排序。在后面我们为用户增加关注人的功能之后,将使用该方法来获取当前用户关注的人发布过的所有微博动态。现在的 feed 方法定义如下:

app/Models/User.php

public function feed()
{
    return $this->statuses()->orderBy('create_at','desc');
}

由于我们在用户模型中已定义好了 feed 方法,因此我们可以在主页对应的控制器动作 home 中使用该方法来获取用户的微博动态。

app/Http/Controllers/StaticPagesController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Auth;

class StaticPagesController extends Controller
{
    public function home()
    {
        $feed_items = [];
        if (Auth::check()){
            $feed_items = Auth::user()->feed()->paginate(30);
        }
        return view('static_pages/home',compact('feed_items'));
    }
    public function help()
    {
        return view('static_pages/help');
    }
    public function about()
    {
        return view('static_pages/about');
    }
}

我们定义了一个空数组 feed_items 来保存微博动态数据。由于用户在访问首页时,可能存在登录或未登录两种状态,因此我们需要确保当前用户已进行登录时才从数据库读取数据。前面章节我们已讲过,可以使用 Auth::check() 来检查用户是否已登录。另外我们还对微博做了分页处理的操作,每页只显示 30 条微博。

现在让我们来接着定义一个微博动态流局部视图,用于渲染微博动态列表。

resources/views/shared/_feed.blade.php

@if($feel_item->count() >0)
    <ul class="list-unstyled">
        @foreach($feed_items as $status)
            @include('statuses._status',['user'=>$status->user])
        @endforeach
    </ul>
    <div class="mt-5">
        {!! $feed_items->render() !!}
    </div>
@else
    <p>没有数据</p>
@endif

在该视图中我们对微博动态数据进行了判断,当取出的微博数据不为空的时候才对视图进行渲染。

接着让我们将该视图添加到网站主页上。

resources/views/static_pages/home.blade.php

@extends('layouts.default')

@section('content')
  @if(Auth::check())
    <div class="row">
      <div class="col-md-8">
        <section class="status_form">
          @include('shared._status_form')
        </section>
        <h4>微博列表</h4>
        <hr>
        @include('shared._feed')
      </div>
      <aside class="col-md-4">
        <section class="user_info">
          @include('shared._user_info',['user'=>Auth::user()])
        </section>
      </aside>
    </div>
  @else
    <div class="jumbotron">
      <h1>Hello Laravel</h1>
      <p class="lead">
        你现在所看到的是 <a href="https://laravel-china.org/courses/laravel-essential-training">Laravel 入门教程</a> 的示例项目主页。
      </p>
      <p>
        一切,将从这里开始。
      </p>
      <p>
        <a class="btn btn-lg btn-success" href="{{ route('signup')}}" role="button">现在注册</a>
      </p>
    </div>
  @endif
@stop

刷新首页,即可看到我们的微博列表:

image.png

Git 代码版本控制

接着让我们将本次更改纳入版本控制中:

$ git add -A
$ git commit -m "首页微博列表"

六、删除微博

现在我们已能够在主页上看到微博动态流的数据展示了。但现在用户还不能删除自己发布过的微博,让我们来加上删除功能。

1、授权策略

我们需要使用授权策略来对用户进行授权删除的操作,只有当被删除的微博作者为当前用户,授权才能通过。运行下面命令生成微博授权策略。

$ php artisan make:policy StatusPolicy

我们需要在该授权策略中引入用户模型和微博模型,并添加 destroy 方法定义微博删除动作相关的授权。如果当前用户的 id 与要删除的微博作者 id 相同时,验证才能通过。

app/Policies/StatusPolicy.php

<?php

namespace App\Policies;

use App\Models\Status;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;

class StatusPolicy
{
    use HandlesAuthorization;

    /**
     * Create a new policy instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    public function destroy(User $user,Status $status)
    {
        return $user->id === $status->user_id;
    }
}

不要忘记,我们还需要在 AuthServiceProvider 中对授权策略进行配置才能正常使用。

app/Providers/AuthServiceProvider.php

<?php

namespace App\Providers;

use App\Models\Status;
use App\Models\User;
use App\Policies\StatusPolicy;
use App\Policies\UserPolicy;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
        User::class => UserPolicy::class,
        Status::class =>StatusPolicy::class,
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        //
    }
}

2、删除按钮

接下来我们要在用户发布过的每一条微博旁边加上一个删除按钮,因此需要把删除按钮加到渲染单条微博的局部视图上。并且删除按钮必须是微博的作者本人才能看到,我们可以很方便的利用 Laravel 授权策略提供的 @can Blade 命令,在 Blade 模板中做授权判断。

resources/views/statuses/_status.blade.php

<li class="media mt-4 mb-4">
    <a href="{{route('users.show',$user->id)}}">
        <img src="{{$user->gravatar()}}" alt="{{$user->name}}" class="mr-3 gravatar"/>
    </a>
    <div class="media-body">
        <h5 class="mt-0 mb-1">{{$user->name}} <small> / {{$status->created_at->diffForHumans()}}</small></h5>
        {{$status->content}}
    </div>

    @can('destroy',$status)
        <form action="{{route('statuses.destroy',$status->id)}}" method="post">
            {{csrf_field()}}
            <button type="submit" class="btn btn-sm btn-danger">删除</button>
        </form>
    @endcan
</li>

3、添加动作

接着我们还需要定义微博动态控制器的 destroy 动作来处理微博的删除:

app/Http/Controllers/StatusesController.php

代码详解:

  public function destroy(Status $status)


这里我们使用的是『隐性路由模型绑定』功能,Laravel 会自动查找并注入对应 ID 的实例对象 $status,如果找不到就会抛出异常。

$this->authorize('destroy', $status);

做删除授权的检测,不通过会抛出 403 异常。

$status->delete();

调用 Eloquent 模型的 delete 方法对该微博进行删除。

session()->flash('success', '微博已被成功删除!');

删除成功之后,将返回到执行删除微博操作的页面上。

4、测试一下

现在,微博删除功能已开发完成,让我们来尝试删除一条微博。

image.png

5、删除确认

我们在做删除功能的产品设计时,考虑『删除』是个危险的动作,一般需要给用户弹出确认框,以防止用户误操作。接下来我们一起来实现删除确认功能:

resources/views/statuses/_status.blade.php

<li class="media mt-4 mb-4">
    <a href="{{route('users.show',$user->id)}}">
        <img src="{{$user->gravatar()}}" alt="{{$user->name}}" class="mr-3 gravatar"/>
    </a>
    <div class="media-body">
        <h5 class="mt-0 mb-1">{{$user->name}} <small> / {{$status->created_at->diffForHumans()}}</small></h5>
        {{$status->content}}
    </div>

    @can('destroy',$status)
        <form action="{{route('statuses.destroy',$status->id)}}" method="post" onsubmit="return confirm('您确定要删除本条微博吗?')">
            {{csrf_field()}}
            {{method_field('DELETE')}}
            <button type="submit" class="btn btn-sm btn-danger">删除</button>
        </form>
    @endcan
</li>

代码分解:

<form action="{{ route('statuses.destroy', $status->id) }}" method="POST" onsubmit="return confirm('您确定要删除本条微博吗?');">

这一行简单 Javascript 代码,即可实现我们想要的功能。刷新页面后再次点击删除按钮,可以看到确认框:

image.png

6、个人页面

还记得我们在个人页面里也加载了 statuses._status 子视图,因为此视图与首页共用,所以当我们在子视图中添加了删除功能后,个人页面的视图也会相应变跟,点击进入用户列表:

image.png

选择进入当前登录用户的个人中心,确定一下是否可以看到删除按钮:


Git 代码版本控制

接着让我们将本次更改纳入版本控制中:

$ git add -A
$ git commit -m "删除微博"

七、小结

最后,我们需要将代码进行提交,并切换到主分支上进行合并。

$ git checkout master
$ git merge user-statuses

接着将代码推送到 GitHub 和 Heroku 上:

$ git push
$ git push heroku master

由于我们新增了微博迁移文件,因此需要在 Heroku 上也需要执行迁移。

$ heroku run php artisan migrate

测试下线上应用:

image.png

经过本章节的学习,我们学到了以下内容:

  • 在两个模型之间使用一对多关联;

  • 通过模型关联来获取数据;

  • 对微博发布时间进行友好化处理,并添加中文版本的支持;

  • 通过数据填充为微博新增假数据;

  • 通过数据关联来创建微博;

  • 修复批量赋值的报错;









回复列表



回复操作

正在加载验证码......

请先拖动验证码到相应位置