2017-07-06 6 views
2

私は現在、自作のhack-y MVCアプローチのModelコンポーネントをphp-activerecordに置き換えています。私は、データベースサーバがダウンし、そのページがゲストアバター、名前、および役割を持つユーザーバッジを表示するために使用された場合に表示される別のページを持っています。コードは以下の通りである:ユーザがどの、ログインしている場合データベース接続のないActiveRecordモデルのインスタンス化

if (Auth::$signed_in) 
    echo Auth::$user->getAvatarWrap(); 
else echo (new \App\Models\User([ 
    'name' => 'Guest', 
    'role' => 'guest', 
    'avatar_url' => GUEST_AVATAR 
]))->getAvatarWrap(); 

Auth::$signed_intrueに設定されている - DBの停止の場合には - 不可能であるので、elseブランチは、事前定義されたデータを用いて実行します。

Pre-ActiveRecordこれはオブジェクトにプロパティを追加するだけで、getAvatarWrapメソッドの呼び出しは問題なく実行されます。現在、ActiveRecordによってモデルが制御されているため、何らかの理由で一連の追加呼び出しが行われます。これは、モデルにリレーションが定義されている可能性がありますが、わかりません。

ActiveRecord\DatabaseException: PDOException: SQLSTATE[08006] [7] could not connect to server: Connection refused 
    Is the server running on host "localhost" (127.0.0.1) and accepting 
    TCP/IP connections on port 5432? in /var/www/vendor/php-activerecord/php-activerecord/lib/Connection.php:260 
Stack trace: 
#0 /var/www/vendor/php-activerecord/php-activerecord/lib/Connection.php(260): PDO->__construct('pgsql:host=loca...', '<username>', '<password>', Array) 
#1 /var/www/vendor/php-activerecord/php-activerecord/lib/Connection.php(122): ActiveRecord\Connection->__construct(Object(stdClass)) 
#2 /var/www/vendor/php-activerecord/php-activerecord/lib/ConnectionManager.php(33): ActiveRecord\Connection::instance('pgsql://databas...') 
#3 /var/www/vendor/php-activerecord/php-activerecord/lib/Table.php(114): ActiveRecord\ConnectionManager::get_connection('pgsql') 
#4 /var/www/vendor/php-activerecord/php-activerecord/lib/Table.php(90): ActiveRecord\Table->reestablish_connection(false) 
#5 /var/www/vendor/php-activerecord/php-activerecord/lib/Table.php(71): ActiveRecord\Table->__construct('App\\Models\\User') 
#6 /var/www/vendor/php-activerecord/php-activerecord/lib/Model.php(765): ActiveRecord\Table::load('App\\Models\\User') 
#7 /var/www/vendor/php-activerecord/php-activerecord/lib/Model.php(271): ActiveRecord\Model::table() 
#8 /var/www/includes/views/_sidebar.php(20): ActiveRecord\Model->__construct(Array) 
#9 /var/www/includes/views/_layout.php(148): include('/var/www...') 
#10 /var/www/includes/views/fatalerr.php(46): require('/var/www...') 
#11 /var/www/includes/init.php(32): require('/var/www...') 
#12 /var/www/includes/do.php(3): require('/var/www...') 
#13 /var/www/public/index.php(1): require('/var/www...') 
#14 {main} in /var/www/vendor/php-activerecord/php-activerecord/lib/Connection.php on line 262 

は、どのように私は、私はそれがものを見つけることができませんという事実を知ったときに、接続を探して停止することはActiveRecordを教えてください、そして、それは私がそれを供給していたデータとコンテンツであることを?停止中に私のモデルを使用することに別れを告げなければなりませんか?

+0

sqlite:memory接続を使用するように設定を変更できますか? – colburton

+0

私はコードとそれが実行されているサーバーの両方を完全に制御しています。 – SeinopSys

+0

これは解決策になる可能性があります。すべてのクエリは失敗しますが、それはどんな場合でも発生します。 – colburton

答えて

0

a commentのおかげで、私は成功への道に私を置くSQLiteメモリデータベースについて知りました。この種のデータベースのサポートを可能にするpull requestがほぼ1年間ダストを集めていることを考えれば、私は自分の手で問題を解決することに決めました。
これを後で読んでいる場合は、そのPRがまだマージされているかどうかを確認し、この回答を更新できるようにコメントが残っていることを確認してください。

まず、original repositoryリポジトリをGitHubにフォークしました。私は意図的に私のフォークをリンクしていません、それは時代遅れになるか、最終的に削除されるかもしれないので、私はあなた自身のためにフォークを作ることをお勧めします。次に、this answerthis answerの組み合わせを使用して、PRの提出者のフォークから私のフォークに魔法の枝を得ました。フォークされたリポジトリのホームページの "クローンまたはダウンロード"ボタンを押して、<url>を取得できます。

$ git clone <url> 
$ git remote add target https://github.com/claytonrcarter/php-activerecord.git 
$ git fetch --all 
$ git checkout master 
$ git merge --squash target/sqlite-memory-support 
$ git commit -m "Add support for SQLite :memory: databases" 
$ git push 

は今私のフォークは、私は私のプロジェクトのcomposer.jsonにかかった最新の変更を持っていた"dev-master"に私のrequireブロックにphp-activerecord/php-activerecordのバージョンを変更したこと、それに私のフォークでrepositoriesブロックを追加しました。ここでも、<url>をフォークのクローンURLに置き換えます。

{ 
    // ... 
    "require": { 
     // ... 
     "php-activerecord/php-activerecord": "dev-master", 
     // ... 
    }, 
    "repositories": [ 
     { 
      "type": "vcs", 
      "url": "<url>" 
     } 
    ] 
} 

しかし、待って、楽しみはそれだけではありません!メモリSQLite DBアダプタをサポートしましたので、実際にはそれを定義する必要があります。だからあなたの初期設定に修正:

ActiveRecord\Config::initialize(function ($cfg){ 
    $cfg->set_connections([ 
     'pgsql' => 'pgsql://'.DB_USER.':'.DB_PASS.'@'.DB_HOST.'/database?charset=utf8', 

     // Add this line below. 'failsafe' can be changed to something else, of course 
     'failsafe' => 'sqlite://:memory:', 
    ], 'pgsql'); 
}); 

は、それがホットスワップにprettydifficultデフォルトの接続ですが判明したので、私は次の最もよい事をした、と前に定義failsafeにその$connectionセットを持っていた子クラスを作りました。 libには、空のデータベースから使用できるフィールドを知る手段がないため、必須フィールドは手動で定義する必要があることに注意してください。興味深いことに、メインクラスに存在していた$has_manyなどの関係は、サブクラスの動作に悪影響を及ぼさないため、比較的短くしておくことができました。

namespace App\Models; 

/** @inheritdoc */ 
class FailsafeUser extends User { 
    static $connection = 'failsafe'; 

    public $name, $role, $avatar_url; 
} 

は最後に、私は、新しく定義したクラスを使用するための呼び出しを変更する必要がありました:

if (Auth::$signed_in) 
    echo Auth::$user->getAvatarWrap(); 
else echo (new \App\Models\FailsafeUser([ 
    'name' => 'Guest', 
    'role' => 'guest', 
    'avatar_url' => GUEST_AVATAR 
]))->getAvatarWrap(); 

ローと見よ、スクリプトもはや休憩をし、私は最終的にのActiveRecordの-ificationに乗ることができます私のコードベース。この拷問を自分自身で行い、複数のモデルを "オフライン"にしたい場合は、コンストラクタで渡したプロパティを自動的に設定する抽象クラスを作成することができます$connectionをあらかじめ設定しておくことで、子インスタンスの作成方法をあまり控えめにすることができます。

関連する問題