2

Laravel Eloquent ORM を使用して、2 つの異なる接続で単純な 1 対 1 の関係を構築しようとしています。

私がそうするとしましょう:

MyModel::on('secondary_connection')->get()

それはうまくいっています。

私がする時 :

MyModel::on('secondary_connection')->with('AnotherModel')->get();

eloquent が ("secondary_connection" ではなく) デフォルト接続で AnotherModel SELECT ステートメントを実行しているため、エラーが発生します。

これを回避する方法が見つかりません。

私のモデルは、デフォルトの接続で結合できるため、明確に定義されています。

考え?

4

5 に答える 5

3

多くのユーザーから提案されているように、その場でこれを行う方法はないようです。これについての私の理解では、マルチ接続の管理に関しては、Eloquent は不完全です。

これを回避するには2つの方法があります。

まず、モデルで接続を指定します。

class MyModel {
    $protected connection = 'secondary_connection';
}

このモデルは 1 つの接続でしか使用できないため、これは明らかに悪い回避策ですが、それでも機能します。

次に、Jarek Tkaczyk が提案したように、デフォルトの接続を新しい接続に切り替えることができます。ただし、構成ファイルで行う代わりに、PDO オブジェクトを交換することができます。

    $default = DB::getPdo(); // Default conn
    $secondary = DB::connection('secondary_connection')->getPdo();
    DB::setPdo($secondary);
    $result = MyModel::with('AnotherModel')->get();
    DB::setPdo($default);

これは機能する回避策であり、クリーンなソリューションになる可能性があります。次のステップは、Laravel の優れた方法でその切り替えメカニズムを配置することです。

于 2015-02-10T19:18:36.917 に答える
0

文字通り、その場でそれを行う方法はありません。

Eloquent が熱心にロードされたモデルに使用するようにするには、デフォルトの接続を変更する必要があります。次のようなヘルパー メソッドでラップできます。

function on($connection, Closure $callback)
{
    // backup default connection
    $default = Config::get('database.default');

    // change for current query
    Config::set('database.default', $connection);

    // run the query
    $result = $callback();

    // restore the default connection
    Config::set('database.default', $default);

    return $result;
}

次に、以下のように呼び出します。

$models = on('secondary_connection', function () {
   return MyModel::with('relation')->get();
});
于 2015-02-09T23:48:58.320 に答える
0

私もこの問題に取り組んでいます。解決策を見つけましたが、.env ファイルを介して使用される接続を構成できる場合にのみ機能します。動的に変更したい場合、これは機能しませんが、その場合は少しロジックを使用して (関数を呼び出して) 正しい接続名を返すことができます。

私が持っている解決策は、Model クラスの connectionName メソッドをオーバーライドすることです。私の場合、これを処理するすべてのモデルの基本クラスがあります。

abstract class ModelBase extends Model
{
    public function getConnectionName()
    {
        return env('ELOQUENT_DB_CONNECTION', parent::getConnectionName());
    }
}

前述したように、必要なロジックを getConnectionName に配置して、より動的にすることができます。

于 2016-05-04T17:23:07.407 に答える
0

単純な関係関数をもう少しカスタムな関数に置き換えることになりました。たとえば、 my->relatedModelは Eloquent Model のオリジナルのコピーのようなものですが、接続の設定が含まれています。

public function relatedModel() {
  $instance = new \relatedModel;
  $instance->setConnection($this->getConnectionName());
  $query = $instance->newQuery();

  return new BelongsTo($query, $this, 'myForeignKey', $instance->getKeyName(), null);
}

私は Laravel 5 を使用しているので、これは 4.2 とは異なる可能性があります。

そして、私はこの問題を何度もいじっていたので、デフォルト以外の接続で検証を行うための素晴らしい方法があります: http://laravel.io/forum/10-29-2014-validation-rules-and-複数のデータベース接続

モデル メソッドの場合は、次のように短縮することもできます。

$v = Validator::make($data, $rules);
$v->getPresenceVerifier()->setConnection($this->getConnectionName());
于 2015-09-18T12:51:49.143 に答える