2017-10-19 19 views
0

私は、対象が複数の関係を持つことができるモーフィング関係を持っています。それらの存在は、モーフィングモデルに依存する。私はすべての関連するモデルを検索する必要があります(whereHas()は問題を解決しません)、関係が常に存在するわけではないので、特定のモデル上に存在する場合、それらの関係がロードされるようにします(with()は機能しません)。リレーションシップが存在する場合にのみ、熱心な負荷

このシナリオを流暢に解決するために使用できるものが他にありますか(ハッキングのみ)。

<?php 

... 

class Post extends Model 
{ 
    /** 
    * Get all of the post's comments. 
    */ 
    public function comments() 
    { 
     return $this->morphMany('App\Comment', 'commentable'); 
    } 

    /** 
    * This relationship is available for Post model only 
    */ 
    public function relationA() 
    { 
     // return $this->hasMany(...); 
    } 
} 

class Video extends Model 
{ 
    /** 
    * Get all of the video's comments. 
    */ 
    public function comments() 
    { 
     return $this->morphMany('App\Comment', 'commentable'); 
    } 

    /** 
    * This relationship is available for Video model only 
    */ 
    public function relationB() 
    { 
     // return $this->hasMany(...); 
    } 
} 

class Comment extends Model 
{ 
    /** 
    * Get all of the owning commentable models. 
    */ 
    public function commentable() 
    { 
     return $this->morphTo(); 
    } 

    public static function feed() 
    { 
     self::with('commentable') 
      ->withIfExists(['commentable.relationA', 'commentable.relationB']) 
      // ... 
      ->get(); 
    } 

    public function scopeWithIfExists($query, $relation) 
    { 
     // There is no way to implement such a scope 
     // in order to reduce umber of queries by eager loading relations 
     // as we don't know of what type the subject is 
     // without looking it up in database 
    } 
} 

答えて

0

チェックアウトはQuery Scopesです。それと

あなたはそれが存在する場合、たとえば、関係をロードするためにスコープを作成することができます。たとえば

User::withRelationIfExists('cars')->where(...) 

:(コードがテストされていない)

public function scopeWithRelationIfExists($query, $relation) 
{ 
    if (! method_exists(get_class(), $relation)) { 
     return; 
    } 

    return $query->with($relation); 
} 
+0

このアプローチは、それを修正しません私の考えでは。それは、それをロードするかどうかを決定しますが、すべてのためにロードします。したがって、現在のモデルで定義された関係を持つか、laravelはそれを読み込もうとしませんし、ロードされません。または私は何かを逃していますか? – notnull

+0

このメソッドは、常時チェックせずにリレーションを簡単に読み込むためのカスタムヘルパーです。それを使用したい場合は、Modelでそのメソッドを宣言するか、継承するParentモデルを作成するか、Traitに追加して、このカスタムスコープで使用するモデルで使用する必要があります。あなたが関係の名前を知らない場合、Laravelに関係を自動的にロードするように指示する方法はありません。 – Lloople

+0

私はスコープについて理解しています。私はそれをあなたの提案と同じように実装しましたが、ある時点では理解できません。あなたがmorphMany関係を持っていれば、オブジェクトのクラスはデータベースに保存されていますいろいろな種類があります)、dbを照会する前にそのような関係が存在するかどうかを確認することはできません。 – notnull

関連する問題