本章將開始探索博客的模型。該模型將使用 Eloquent 對象關系映射(ORM)實現,還會介紹如何填充測試數據,它是一個有利于我們進行開發和測試數據庫的好途徑。在文章結束后,你將會了解如何定義模型,更新數據庫并創建一些可用于測試的填充數據,還將了解如何構建用于展示博客頁面的基礎知識。
Eloquent
對于我們的博客來說,我們需要一種持久化數據的方法。而 Laravel 的 Eloquent ORM 提供了漂亮、簡潔的 ActiveRecord 實現來和數據庫進行交互。每個數據庫表都有一個對應的「模型」可用來跟數據表進行交互。讓給你可以通過模型查找數據表內的數據,以及將記錄添加到數據表中。
對象關系映射(英語:(Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping),是一種程序技術,用于實現面向對象編程語言里不同類型系統的數據之間的轉換。
ORM 有助于將關系數據庫(如MySQL)的數據轉換為可以操作的 PHP 對象。這使我們能夠在類中的表上封裝我們需要的功能。想想一個用戶表,它可能有用戶名,密碼等字段。使用ORM,我們將操作的是一個包含成員用戶名,密碼等內容的類,它允許我們調用相應的方法來對數據實體進行操作。隨著我們在本教程中的進展,你將更加熟悉 ORM 的內容。
文章模型
讓我們先來創建文章模型。
模型通常放在 app 目錄中,不過你可以將他們隨意放在任何可通過 composer.json 自動加載的地方。所有的 Eloquent 模型都繼承自 Illuminate\Database\Eloquent\Model 類。
通過命令行進入項目所在目錄,執行如下命令:
php artisan make:model Post -m
命令會生成模型 app/Post.php
和數據庫遷移文件 database/migrations/xxxx_xx_xx_xxxxxx_create_posts_table.php
。
如果你留意,在
database/migrations
下已存在2014_10_12_000000_create_users_table.php
和2014_10_12_100000_create_password_resets_table.php
,這是 Laravel 框架自帶的默認用戶功能的一部分,這個自帶的數據遷移可以讓你快速構建用戶和認證信息的存儲,如果你用不到用戶功能,是可以刪除它們的。
關于數據庫
我們在項目創建之初就已經建立了數據庫 larablog
,此時我們定義了模型,我們將通過數據遷移來建立和維護其中的數據表。
文章表
找到我們生成 Post
模型時生成的遷移文件 database/migrations/xxxx_xx_xx_xxxxxx_create_posts_table.php
。更改為如下內容:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('author', 100);
$table->text('content');
$table->string('image');
$table->text('tags');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('posts');
}
}
在遷移文件中,我們定義了 posts
表的結構,設置了不同字段的類型和長度。
關于數據遷移的更多內容可以查閱文檔 數據遷移
接下來,我們要需要通過命令 php artisan migrate
來執行數據遷移,創建我們需要的表。
執行效果如下:
larablog php artisan migrate
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2017_07_10_075949_create_posts_table
其中 users
和 password_resets
這 2 個遷移之前提到過是框架自帶,我們可以看創建表 posts
的遷移也已經執行。我們可以通過 http://localhost/phpmyadmin/
去查看我們的數據 larablog
現在的情況。可以看到我們想要的表 posts
已經成功的創建了。
默認情況下,Eloquent 會預計你的數據表中有 created_at 和 updated_at 字段。如果你不希望讓 Eloquent 來自動維護這兩個字段,可在模型內將 $timestamps 屬性設置為 false:
詳細信息可以查閱 eloquent 時間戳
整合模型和視圖
現在我們創建了文章模型,并更新了數據庫創建了相應的數據表,我們可以開始將模型集成到視圖中。將開始構建我們博客的展示頁面。
路由
首先打開 app/Http/routes.php
文件,增加文章相關的路由配置:
Route::resource('posts','PostsController');
可以發現,這和之前定義的 GET
, POST
請求路由不同,這是一個資源路由。
這條資源路由聲明會創建多個路由,用來處理各式各樣和相片資源相關的的 RESTful 行為。同樣地,生成的控制器有著各種和這些行為綁定的方法,包含要處理的 URI 及方法對應的注釋。
更多關于資源路由的信息可以查閱這里的文檔 RESTful-資源控制器
接下來我們生成控制器 PostsController
。通過命令行進入項目所在目錄,執行命令:
php artisan make:controller PostsController
生成的 PostsController
就是一個資源類型的控制器,可以看到它內部已經幫我們定義好了很多控制器方法。
接下來看看我們定義路由,繼續執行如下命令:
php artisan route:list
將會呈現應用的所有路由信息:
? larablog php artisan route:list
+--------+----------+--------------------+---------------+-------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+--------------------+---------------+-------------------------------------------------+------------+
| | GET|HEAD | / | homepage | App\Http\Controllers\PageController@index | |
| | GET|HEAD | about | about | App\Http\Controllers\PageController@about | |
| | GET|HEAD | contact | contact | App\Http\Controllers\PageController@contact | |
| | POST | contact | | App\Http\Controllers\PageController@postContact | |
| | GET|HEAD | posts | posts.index | App\Http\Controllers\PostsController@index | |
| | POST | posts | posts.store | App\Http\Controllers\PostsController@store | |
| | GET|HEAD | posts/create | posts.create | App\Http\Controllers\PostsController@create | |
| | GET|HEAD | posts/{posts} | posts.show | App\Http\Controllers\PostsController@show | |
| | PUT | posts/{posts} | posts.update | App\Http\Controllers\PostsController@update | |
| | PATCH | posts/{posts} | | App\Http\Controllers\PostsController@update | |
| | DELETE | posts/{posts} | posts.destroy | App\Http\Controllers\PostsController@destroy | |
| | GET|HEAD | posts/{posts}/edit | posts.edit | App\Http\Controllers\PostsController@edit | |
+--------+----------+--------------------+---------------+-------------------------------------------------+------------+
現在我們能清晰的看到我們所定義的資源路由 posts
的明細。考慮到我們后續應該會對文章進行操作一些操作,比如;編輯,刪除。資源路由就包含了這些操作文章的請求,我們將文章做為一種資源為其定義資源路由很符合我們的需要,如果你在定義路由時,盡可能考慮你是否要需要這么定義路由信息。
控制方法
我們已經建立了控制器 app/Http/Controllers/PostsController.php
,接下來我們定位到 show
方法:
public function show($id)
{
$post = Post::findOrFail($id);
return view('posts.show', ['post' => $post]);
}
這里,我們通過模型來查找相應 id
的文章,并渲染視圖顯示內容。如果文章不存在將會拋出異常 NotFoundHttpException
。
如果是生產環境,這樣的異常信息最終都會以 404 頁呈現給用戶,這需要我們自己定制相關的異常錯誤處理頁面,關于這方面的內容這里就不展開了。
視圖顯示
現在我們已建立控制方法 show
來處理文章的顯示。我們需要創建文件 resources/views/posts/show.blade.php
并添加如下內容:
@extends('layouts.app')
@section('title', $post->title)
@section('body')
<article class="blog">
<header>
<div class="date">{{ $post->created_at->format('l, F j, Y') }}</div>
<h2>{{ $post->title }}</h2>
</header>
<img src="{{ asset('images/'.$post->image) }}" alt="{{ $post->title }} image not found" class="large" />
<div>
<p>{{ $post->content }}</p>
</div>
</article>
@endsection
我們將文章使用的圖片信息存放在了
public/images
下,你可以通過下面的鏈接獲得這些靜態圖片資源。
圖片資源
CSS
同時我們要為博客的內容增加樣式信息,打開文件 public/css/blog.css
,追加如下內容:
.date { margin-bottom: 20px; border-bottom: 1px solid #ccc; font-size: 24px; color: #666; line-height: 30px }
.blog { margin-bottom: 20px; }
.blog img { width: 190px; float: left; padding: 5px; border: 1px solid #ccc; margin: 0 10px 10px 0; }
.blog .meta { clear: left; margin-bottom: 20px; }
.blog .snippet p.continue { margin-bottom: 0; text-align: right; }
.blog .meta { font-style: italic; font-size: 12px; color: #666; }
.blog .meta p { margin-bottom: 5px; line-height: 1.2em; }
.blog img.large { width: 300px; min-height: 165px; }
填充數據
Laravel 可以簡單的使用 seed
類來給數據庫填充測試數據。所有的 seed
類都放在 database/seeds
目錄下。你可以任意地為 Seed 類命名,但是應該遵守某些大小寫規范,可用類似 UserTableSeeder 之類的命名。 Laravel 默認為你定義了一個 DatabaseSeeder 類。你可以在這個類中使用 call 方法來運行其它的 seed
類,以借此控制數據填充的順序。
接下來我們就創建編寫數據填充類。命令行下進入項目所在目錄,執行命令:
php artisan make:seeder PostsTableSeeder
執行完命令,文章數據填充類就會生成,文件位于 database/seeds/PostsTableSeeder.php
,內容如下:
<?php
use Illuminate\Database\Seeder;
class PostsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
}
}
在 seeder 類里只有一個默認方法:run。當運行 db:seed Artisan 命令 時就會調用此方法。你可以在 run 方法中給數據庫添加任何數據。你可使用 查詢語句構造器 或 Eloquent 模型工廠 來手動添加數據。
這個 run
方法中我們可以添加如下方法手動插入數據:
/**
* 運行數據庫填充。
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
'name' => str_random(10),
'email' => str_random(10).'@gmail.com',
'password' => bcrypt('secret'),
]);
}
這只是個樣例寫法,很顯然我們每次都要一條條的插入測試數據會不方便,當我們需要填充很多測試數據時,我們可以利用填充數據的模型工廠來建立數據模板。
數據模板
打開 database/factories/ModelFactory.php
文件,可以看到默認存在了 User
模型的數據模板,構建用戶數據時就可以很方便的生成相應的數據。現在讓我們來構建 Post
模型的數據模版,在文件中添加如下內容:
$factory->define(App\Post::class, function (Faker\Generator $faker) {
return [
'title' => $faker->sentence(6),
'content' => $faker->text(600),
'image' => $faker->randomElement(['beach.jpg', 'misdirection.jpg', 'one_or_zero.jpg', 'pool_leak.jpg', 'the_grid.jpg']),
'author' => $faker->name,
'tags' => join(',', $faker->words(rand(3, 6)))
];
});
在這里,我們定義了一個 Post
模型的數據模板,接下來我們會在填充數據時根據數據模板來生成特定數量的數據。
數據模板中有很多數據生成的方法這是通過集成的組件完成的.
Faker is a PHP library that generates fake data for you.
你可以通過這里了解它 Faker
更新我們的文件 database/seeds/PostsTableSeeder.php
,修改 run
方法的內容:
public function run()
{
factory(App\Post::class, 50)->create();
}
修改 database/seeds/DatabaseSeeder.php
,同樣修改 run
方法:
public function run()
{
Model::unguard();
$this->call(PostsTableSeeder::class);
Model::reguard();
}
這里,數據填充器將會調用文章填充類通過文章模型數據模板生成 50
個樣板數據到數據庫。
命令
最終的數據填充需要執行命令來完成,讓我們在命令行下進入項目所在目錄執行 php artisan db:seed
:
? larablog php artisan db:seed
Seeded: PostsTableSeeder
命令執行完成,我們可以通過 http://localhost/phpmyadmin
來查看生成的填充數據。
有了填充數據,我們的博客內容可以顯示了。打開瀏覽器訪問 http://localhost:8000/posts/1
即可查看編號為 1
的博客內容(當然你還可以試試別的編號)。
至此,我們完成了博客內容的顯示,并通過填充測試數據很輕松的就讓顯示效果得以展現。
總結
在本章的內容中我們提及了一些 Eloquent 的概念和基本用法,我們也看到了填充數據可以讓我們可以快速的為應用添加測試數據。
接下來,我們會試著通過添加評論來延伸更多模型功能,我們會開始建立首頁,將繼續探討數據遷移的使用以及如何通過 Eloquent 模型將評論發布到博客中。