PHPフレームワークLaravelのフォーム開発
マイグレーションとデータベーステーブルの定義
Laravelでシンプルなフォームを作成します。
フォームから実際にデータをサーバ側へ送信するので、最初にDBのテーブルを作成します。Laravelでは、Railsと同等のデータベーステーブルをマイグレーション管理する機能が備わっているので、その機能を使ってテーブルを定義します。
php artisan migrate:make create_engineers_table --table=engineers --create
artisanコマンドを使って、マイグレーションファイルを作成します。コマンドを実行すると
app/database/migrations/2014_09_27_200426_create_engineers_table.php
上のマイグレーションファイルが作成されますので、up functioonでテーブルの構造を定義します。
public function up() { Schema::create('engineers', function(Blueprint $table) { $table->increments('id'); $table->text('name'); }); }
idとnameフィールドで構成されたテーブル構造を定義した例になります。migrateコマンドを実行してデータベースに反映させます。
php artisan migrate
Modelのコーディング
engineersテーブルを作成したので、対応するModelをコーディングします。
app/models/Engineer.php
上のファイル名で、下のコードを追加します。
class Engineer extends Eloquent { protected $table = 'engineers'; protected $fillable = array('name'); public $timestamps = false; }
$fillableプロパティを設定することで、フォームからデータを登録可能な状態にすることが出来ます。公式のドキュメントでは、Mass Assignmentで解説されています。
route/controllerのコーディング
app/routes.php
でリクエストを受け付け、データの取得とviewへデータを渡すコントローラ的な処理をコーディングします。
Route::get('/', function() { // データの取得 $engineers = Engineer::all(); // 取得したデータをviewに渡す return View::make('form')->with('engineers', $engineers); });
上のコードでアプリケーションのルート(/)に対するGetリクエストを処理することが可能になり、データの一覧を表示することが出来ます。
フォームを送信した際に処理するPOSTリクエスト用のコードは後述します。
Viewのコーディング
Laravelの標準テンプレートに設定されているBladeを使って、フォームのHTMLを作成します。
Layout
app/views/layout.blade.php
<!DOCTYPE html> <html lang="en"> <head> <title>Laravelのフォーム</title> <link rel="stylesheet" href="http://cdn.foundation5.zurb.com/foundation.css" /> </head> <body> @yield('content') </body> </html>
レイアウトとしてbodyタグ内部以外の部分を作成しました。次にコンテンツ部分を作成します。
Content
app/views/form.blade.php
@extends('layout') @section('content') <div id="container"> <div class="row"> <div class="large-12 columns"> <h1>エンジニア登録</h1> @if(Session::has('errors')) <div data-alert class="alert-box alert round">{{$errors->first('name')}}</div> @endif @if(Session::has('success')) <div data-alert class="alert-box success radius">{{Session::get('success')}}</div> @endif @if(Session::has('duplicate')) <div data-alert class="alert-box info radius">{{Session::get('duplicate')}}</div> @endif {{Form::open(array('url'=>'/', 'method'=>'post'))}} {{Form::text('name', Input::old('name'), array( 'placeholder' => 'エンジニアの名前を入力してください') )}} {{Form::submit('登録', ['class' => 'button'])}} {{Form::close()}} </div> <div class="large-12 columns"> <h1>エンジニア一覧</h1> <ul> @foreach ($engineers as $e) <li> {{ $e->name }} </li> @endforeach </ul> </div> </div> </div> @stop
コンテンツ部分では上から
- バリデーションや登録完了のメッセージをセッションで制御
- BladeでフォームのHTMLを出力
- Bladeのforeachでデータを繰り返し表示
の順にコーディングしてあります。
route/controllerのコーディング POSTリクエスト
フォームのsubmitボタンを押した時に送信されるPOSTメソッドの処理部分です。バリデーションのエラーメッセージを日本語にする場合は、Laravelのロケールを変更してエラーメッセージを日本語にするのエントリーが参考になります。
Route::post('/',function(){ // バリデーションのルール定義 $rules = array( 'name' => 'required' ); // バリデーション設定 $validation = Validator::make(Input::all(), $rules); // バリデーションNG if($validation->fails()) { // リダイレクトしてエラーメッセージを表示 withInputでフォームの内容を維持することが可能 return Redirect::to('/') ->withInput() ->withErrors($validation); } else { // 同じ名前が既に登録されているか確認 $engineer = Engineer::where('name', '=', Input::get('name')) ->first(); // 登録済みの場合はリダイレクト if($engineer) { return Redirect::to('/') ->withInput() ->with('duplicate', Input::get('name').'は登録されています'); } else { // 未登録の場合はデータベースに追加 Engineer::create(array( 'name' => Input::get('name'), )); // 登録後にリダイレクト return Redirect::to('/') ->with('success', '登録されました'); } } });
はじめまして、キリンと申します。
こちらのサイトを参考にララベルの勉強をさせていただいています。
質問があるのですがよろしいでしょうか。
routes.phpからmodelの継承がうまくいかず、このようなエラーが出てしまいました。よろしければ教えてください。composer dump-autoloadはしております。よろしくお願いします。
ビュー
class Engineer extends Eloquent { protected $table = ‘engineer’; protected $fillable = array(‘name’); public $timestamps = false; } //このコードがなぜかビューに表示されます
Whoops, looks like something went wrong.
ララベルログ
production.ERROR: exception ‘Symfony\Component\Debug\Exception\FatalErrorException’ with message ‘Class ‘Engineer’ not found’ in /home/study/app/routes.php:16
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleShutdown()
#1 {main} [] []