非常に簡単です:
public function bs()
{
$database = $this->getConnection()->getDatabaseName();
return $this->belongsToMany('B', "$database.a_bs", 'a_id', 'b_id');
}
接続が環境変数に基づいて構成されているため、データベース名を動的に取得しています。 Laravelは、ピボットテーブルがターゲットリレーションと同じデータベースに存在すると想定しているようです。そのため、代わりに、このメソッドが含まれるモデルである「A」レルムに対応するデータベースを参照するように強制されます。
SQLiteデータベースについて心配していない場合、つまり単体テストの範囲内であれば、必要なのはそれだけです。しかし、もしそうなら、読み続けてください。
まず、前の例だけでは不十分です。 $ databaseの値は最終的にファイルパスになるため、SQLステートメントを壊さないものにエイリアスを設定し、現在の接続にアクセスできるようにする必要があります。 "ATTACH DATABASE '$database' AS $name"
それを行う方法です:
public function bs()
{
$database = $this->getConnection()->getDatabaseName();
if (is_file($database)) {
$connection = app('B')->getConnection()->getName();
$name = $this->getConnection()->getName();
\Illuminate\Support\Facades\DB::connection($connection)->statement("ATTACH DATABASE '$database' AS $name");
$database = $name;
}
return $this->belongsToMany('B', "$database.a_bs", 'a_id', 'b_id');
}
警告:トランザクションはこれを台無しにします: 現在の接続がトランザクションを使用している場合、ATTACHDATABASEステートメントは失敗します。 できます 後にトランザクションを使用する ただし、そのステートメントを実行します。
一方、関連 接続がトランザクションを使用する場合、結果のデータは現在のデータからはサイレントに非表示になります。私のクエリはエラーなしで実行されましたが、空のままになっていたので、これは私が認めるよりも長い間私を狂わせました。アタッチされたデータベースに実際に書き込まれたデータのみが、アタッチされたデータベースに実際にアクセスできるようです。
したがって、接続されたデータベースへの書き込みを強制された後でも、テストをそれ自体の後でクリーンアップする必要がある場合があります。簡単な解決策は、$this->artisan('migrate:rollback', ['--database' => $attachedConnectionName]);
を使用することです。 。ただし、同じテーブルを必要とする複数のテストがある場合、毎回再構築する必要があるため、これはあまり効率的ではありません。
より良いオプションは、テーブルを切り捨てることですが、その構造はそのままにしておきます:
//Get all tables within the attached database
collect(DB::connection($database)->select("SELECT name FROM sqlite_master WHERE type = 'table'"))->each(function ($table) use ($name) {
//Clear all entries for the table
DB::connection($database)->delete("DELETE FROM '$table->name'");
//Reset any auto-incremented index value
DB::connection($database)->delete("DELETE FROM sqlite_sequence WHERE name = '$table->name'");
});
}
これにより、その接続からすべてのデータが消去されます 、しかし、あなたが適切だと思う方法でそれに何らかの種類のフィルターを適用できなかった理由はありません。または、SQLite DBが簡単にアクセスできるファイルであるという事実を利用して、添付されたファイルを一時ファイルにコピーし、テストの実行後にソースを上書きするために使用することもできます。結果は、トランザクションと機能的に同じになります。