web-dev-qa-db-ja.com

Laravelマージ関係

Laravelで2つの関係をマージする方法はありますか?

これが現在の設定方法ですが、両方をマージして返す方法はありますか?

  public function CompetitionsHome() {
    return $this->HasMany( 'Competition', 'home_team_id' );
  }
  public function CompetitionsGuest() {
    return $this->HasMany( 'Competition', 'guest_team_id' );
  }
  public function Competitions() {
    // return both CompetitionsHome & CompetitionsGuest
  }
16
Kiwi

リレーションから返されたマージされたコレクションを返すプロパティのgetterメソッドを試してください。

public function getCompetitionsAttribute($value)
{
    // There two calls return collections
    // as defined in relations.
    $competitionsHome = $this->competitionsHome;
    $competitionsGuest = $this->competitionsGuest;

    // Merge collections and return single collection.
    return $competitionsHome->merge($competitionsGuest);
}

または、コレクションが返される前に追加のメソッドを呼び出して、さまざまな結果セットを取得することもできます。

public function getCompetitionsAttribute($value)
{
    // There two calls return collections
    // as defined in relations.
    // `latest()` method is shorthand for `orderBy('created_at', 'desc')`
    // method call.
    $competitionsHome = $this->competitionsHome()->latest()->get();
    $competitionsGuest = $this->competitionsGuest()->latest()->get();

    // Merge collections and return single collection.
    return $competitionsHome->merge($competitionsGuest);
}
21
Andreyco

2つのコレクション(関係)を組み合わせるためにmerge()メソッドを使用する場合は、同じインデックスキーを持つ要素をオーバーライドするため、1つの関係から取得したデータの一部が失われます。

代わりにPush()メソッドを選択する必要があります。このメソッドは、1つのコレクションを他のコレクションの最後にプッシュすることによって新しい配列キーを作成します。

ここにサンプルがあります:

public function getCompetitionsAttribute($value) {
    $competitionsHome = $this->competitionsHome;
    $competitionsGuest = $this->competitionsGuest;

    // Push ONE TO OTHER!
    return $competitionsHome->Push($competitionsGuest);
}
5
spetsnaz

グーグルのために誰かが私のようにここに着陸した場合:merge()もPush()も熱心な読み込み(および他の素敵な関係機能)を許可しないので、議論はこのスレッドで終わっていませんでしたが、ここで続けられました: Laravel Eloquent自己参照テーブルの内部結合

私は解決策を提案しました ここ 、この問題へのさらなるアイデアと貢献を歓迎します。

0
tomstig

ビューを使用して関係をマージするためのパッケージを作成しました。
https://github.com/staudenmeir/laravel-merged-relations

まず、移行でマージビューを作成します。

use Staudenmeir\LaravelMergedRelations\Facades\Schema;

Schema::createMergeView(
    'competitions',
    [(new YourModel)->CompetitionsHome(), (new YourModel)->CompetitionsGuest()]
);

次に、関係を定義します。

class YourModel extends Model
{
    use \Staudenmeir\LaravelMergedRelations\Eloquent\HasMergedRelationships;

    public function competitions()
    {
        return $this->mergedRelationWithModel(Competition::class, 'competitions');
    }
}

他の関係と同じように使用します。

$model->competitions;

$model->competitions()->paginate();

YourModel::with('competitions')->get();
0