「鉄は熱いうちに打て」というやつです。
laravel製軽量フレームワーク Lumenを試してみるの続き的な感じです。
記事を読むのが面倒な方は、githubとgistsを見たらなんとかなると思います。
今回の完成形のコードと設定ファイルを置いてます。
趣旨
LumenでORMとMigrationを使ってみる
方向性
- 書きっぱなしのメモアプリを目指す。
- スキーマはid, body, 日付くらいで良いかな
- DBはSQLiteを使います。
前回のおさらい
一からプロジェクトを作りたいので以下のコマンドを叩く。
lumen new memo
DB用のディレクトリを作成
ドキュメントの引用
If you would like to use database migrations with Lumen, you should run the
php artisan make database
Artisan command. This command will create a database directory in your project root which contains migrations and seeds directories.
For further information on how to create database tables and run migrations, check out the Laravel documentation on the schema builder and migrator.
意訳:php artisan make database
でDB用のディレクトリとか作れるけど、詳しくはLaravelのドキュメントとか見てね。
叩くと一番上の階層にdatabasesディレクトリが作成されて、以下の様なディレクトリ構成になる
.
├── app
│ ├── Console
│ ├── Exceptions
│ ├── Http
│ ├── Jobs
│ └── Providers
├── artisan
├── bootstrap
│ └── app.php
├── composer.json
├── composer.lock
├── database
│ ├── migrations
│ └── seeds
├── phpunit.xml
├── public
│ └── index.php
├── readme.md
├── server.php
├── storage
│ ├── app
│ ├── framework
│ └── logs
Laravelのドキュメントを読んでSQLiteを設定する
Laravelではapplication/config/database.php
で設定して、storage/databases
フォルダに適切な名前のファイルを設置したらOKと書いてある。
Lumenではどうなるか試した所結果
- DBの設定は
.env
で設定する - DBファイルは同様に設置する
以下は試行錯誤の結果
.env
トップディレクトリに.env.example
があるのでそれをコピーして書き直す
APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomKey!!!
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
+DB_CONNECTION=sqlite
-DB_CONNECTION=mysql
-DB_HOST=localhost
-DB_DATABASE=homestead
-DB_DATABASE=homestead
-DB_USERNAME=homested
-DB_PASSWORD=secret
+#DB_HOST=localhost
+#DB_DATABASE=homestead
+#DB_DATABASE=homestead
+#DB_USERNAME=homested
+#DB_PASSWORD=secret
CACHE_DRIVER=memcached
SESSION_DRIVER=memcached
QUEUE_DRIVER=database
# FILESYSTEM_DRIVER=local
# FILESYSTEM_CLOUD=s3
# S3_KEY=null
# S3_SECRET=null
# S3_REGION=null
# S3_BUCKET=null
# RACKSPACE_USERNAME=null
# RACKSPACE_KEY=null
# RACKSPACE_CONTAINER=null
# RACKSPACE_REGION=null
また.envを書いた場合、bootstrap/app.php
内に書いてある、Dotenv::load()
のコメントアウトを外しなさい書いてあるので外します。
DBファイル
今回はstorage/database.sqlite
という形で設置した。tocuh
コマンドで作ればok
結果論として
.envの設定が有効にならない気がする。
最初に想定していた設定
DB_CONNECTION=sqlite
DB_DATABASE=memo.sqlite
というのも最初はmemo.sqliteというファイル名で実行するつもりだったが、後のmigrate:install
で上手く実行できず、エラーの手前で設定を出力したら以下のとおりになっていた。
array(4) {
["driver"]=>
string(6) "sqlite"
["database"]=>
string(64) "/path/to/memo/storage/database.sqlite"
["prefix"]=>
string(0) ""
["name"]=>
string(6) "sqlite"
}
自分にLaravelの知識が対して無いためなのか、それともドキュメントの見落としか、バグなのかは定かで無いのですが、時間が有るときにコードを追ってみます。
明らかに間違っていれば、どなたかツッコミをお願いします。
スキーマの設定
Laravelのドキュメントを見つつ、マイグレーションでいい感じにやっていきます。
まずマイグレーションをしていくよ!ということを宣言します。
php artisan migrate:install
うまくいくと以下のようにコメントが出る
Migration table created successfully.
で、実際にマイグレーションファイルをつくる。
このコマンドで生成されるファイルはdatabase/migrations
に設置される
php artisan make:migration create_posts_table
生成されたmigrationファイルを編集する。
upには今回欲しいid,contentと時間を生成するコードを記述。
downにはテーブルを削除するコードを入れておく。
<?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->text('body');
+ $table->timestamps();
+ });
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
+ Schema::drop('posts');
}
}
で、実行の前にbootstrap/app.php
を編集して、以下二行をコメントイン
#もしかしたらEloquentはこの段階では不要かもしれませんが
$app->withFacades();
$app->withEloquent();
実行
php artisan migrate
うまくいくと
Migrated: ~~
ORMの設定
Eloquentと言うやつを使う。まずはファイルの設置から。
今回はapp/Http/Models
というディレクトリを作成し、そこにPost.php
を設置した。
ネームスペースの宣言と、Illuminate\Database\Eloquent\Model
の継承が必要。またクラス変数$tables
にテーブル名を設定
<?php namespace App\Http\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
protected $table = 'posts';
}
ORMの利用
routes.phpは、/posts
にgetしたら一覧と登録フォーム、postしたらメモの内容を登録してリダイレクトという形でコードを書き換える
#先ほど作成したPostを利用するよ
use App\Http\Models\Post;
$app->get('/', function() use ($app) {
return $app->welcome();
});
$app->get('/posts',function() use($app){
#resoureces/posts/index.blade.phpを参照
# 変数として、postsに postsテーブルからの全てのデータを代入
return view('post/index',['posts'=>Post::all()]);
});
$app->post('/posts',function() use($app){
# リクエスト内容を登録
Post::create(Request::all());
#LaravelのRidirectクラスとは異なり、redirect関数を利用する
return redirect('/posts');
});
また/posts
の見た目を軽く作る
以下は/resources/posts/index.blade.php
<form action="/posts" method="post">
<input type="text" name="body" placeholder="メモ欄">
<input type="submit" value="登録">
</form>
<ul>
<li>メモ一覧</li>
@foreach ($posts as $post)
<li>{{$post->body}}</li>
@endforeach
</ul>
最後にPost
でcreate
メソッドを利用する際に、どの値を利用するかの設定を書き足す
<?php namespace App\Http\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
protected $table = 'posts';
+ #保存時の引数のkeyとしてbodyは許可するよ
+ protected $fillable = array('body');
}
以上の様にコードを書きlocalhostで動かして試すと以下の様な画面になると思う。
最後の設定
おそらく、本記事にそってコードを書いていると、連続でpostが出来ない。
理由はキャッシュエンジンにmemcachedが設定されているためなので、.env
を書き換える必要がある
-CACHE_DRIVER=memcached
-SESSION_DRIVER=memcached
+CACHE_DRIVER=file
+SESSION_DRIVER=file
書き換えることで、連続でpostすることも可能になる。
めんどうなので削除とかは書かないが、ドキュメントを見たらすぐに書けると思う。
終わりに
Laravelの知識が無いので不正確な部分もあるかと思います。
指摘をしていただければできるだけ早く修正をするのでよろしくお願い致します。