Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
9
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@ytake

laravel4を使ったアプリケーション配布時の工夫

再び3回目の登場です。

ぼちぼち日本語情報も多くなってきましたので、
laravel4を採用して構築している企業や個人の方も多いのではないでしょうか?(すてき!)

アプリケーションをパッケージにして配布したい時に、
是非組込みたいものがあります。

migrate

laravel4はDBのセットアップも全てフレームワークがやってくれます。
それをコマンドから実行ではなく、
アプリケーションの中にセットアップ項目として取り込みます、というサンプルです。
ただし、先にDBとユーザー名、パスワードは作ってください! (4.1で追加された機能でできたりするのかな?)

まずmigrationsを作っていきます
ファイル名はテーブル名になります。
configuresという設定用テーブルを作るとします

app/database/migrations/YYYY_MM_DD_123456_configures.php
use Illuminate\Database\Migrations\Migration;

class Configures extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        //
        //create
        Schema::create('configures', function($table)
        {
            $table->increments('configure_id');
            $table->string('configure_name', 255);
            $table->text('configure_value');
            $table->timestamps();
            $table->index('configure_name');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        //
    }
}

定義は上記の様に指定したとします。
routesも作ってしまいます

app/routes.php
Route::get('/setup', 'SetUpController@getSetup');
Route::get('/setup/start', 'SetUpController@getSetupStart');

セットアップ確認画面とセットアップ実行的なものをつくっておきましょう
最初はもちろんテーブル自体が存在しない為エラーになります。
とりあえずexception extendsします

適当なところ/DatabaseConfigException.php
class DatabaseConfigException extends \Exception{}

それではいざ実装!
大体みなさんDBだと思いますが、色んなパターンがあり得るでしょう!
より実務的にinterfaceから実装していきます。
場所はどこでも構いません。
例えばロジックはmodelsにまとめるのであれば・・

interface

app/models/Interfaces/DatastoreInterface.php
namespace Model\Interfaces;
interface DatastoreInterface {

    public function get();
}

model

app/models/DbMigrate.php
namespace Model;
use Illuminate\Support\Facades\DB;

class DbMigrate implements Interfaces\DatastoreInterface
{
    public function get()
    {
        try{
            // 
            return DB::connection()->table('configures')->get();

        }catch(\Exception $e){
            // configureテーブルが見つからない場合にthrow
            if(strpos($e->getMessage(), 'SQLSTATE[42S02]') !== false)
            {
                throw new \Extensions\DatabaseConfigException('configures data not found', 900);
            }
        }
    }
}

configuresテーブルが無ければ、アプリケーションに必要なテーブルが無い!
と扱います。

とりあえずmysql向けにしましたが、
アプリケーション利用者が必ずしもmysqlとは限らないはずなので、
他のdbの場合はimplementsして同じ様に実装してもらえればいいでしょう

controller実装

SetupController.php
use Illuminate\Support\Facades\Artisan;
class SetupController extends BaseController {

    private $_datastore;

    public function __construct(Model\Interfaces\DatastoreInterface $data)
    {
        $this->_datastore = $data;
    }

    public function getSetup()
    {
        try { 
            $this->_datastore->get();

        }catch(\Extensions\DatabaseConfigException $e){

            $configure = Config::get('database');
            $data = [
                'default' => $configure['default'],
                'connections' => $configure['connections'][$configure['default']]
            ];
            var_dump($data);
            var_dump(app_path() ."/config/". app()->environment() . "/database.php");
        }
    }

    /**
     * 
     */
    public function getSetupStart()
    {
        Artisan::call('migrate');

    }
}

DBが存在しない場合は、exceptionを投げてきますので、
catchして現在の環境を表示してみました。
database 1台環境のソースですので
databaseを複数使用されている場合は、driverとdefaultから見つけてあげましょう
環境ファイルのパスは恐らくそこにあるでしょう、ということで
利用者にそこのファイル内容を変更してくださいと促してみましょう。

完了後に/setup/startに遷移すれば、migrateが実行される様にしました。
コマンドが苦手なユーザーも、これで安心です

もちろん、このままではエラーですので、
App::bind('Model\Interfaces\DatastoreInterface', 'Model\DbMigrate');
を忘れずに!

という実装は如何でしょうか?\
明日は、websocket+redis pub/sub + laravel4です

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
9
Help us understand the problem. What are the problem?