2

Laravel 4には次のテーブルがあります

 - items table
 --- id
 --- name


 - tags table
 --- id
 --- name

 - item_tag
 --- id
 --- tag_id
 --- item_id
 --- created_at
 --- updated_at



class Item extends Eloquent {

    public function tags()
    {
        return $this->belongsToMany('Tag');
    }
}





class Tag extends Eloquent {

    public function items()
    {
       return $this->hasMany('Item');
    }
}

私の質問:

次の 2 つのタグ「foo」と「bar」を持つすべてのアイテムを取得したいですか? 両方のタグが付いているアイテムのみを返品する必要があります!?

アップデート

以下を試してみましたが、うまくいきませんでした。問題は「->having」句にあると感じていますが、うまくいきませんでした。

タグ「foo」の ID が 1 で、「bar」の ID が 2 であると仮定します。

class Item extends Eloquent {

protected $table = 'items';

public function tags()
{
    return $this->belongsToMany('Tag');
}

 public static function withTags()
{
  return static::leftJoin(
    'item_tag',
    'items.id', '=', 'item_tag.item_id'
  )
  ->whereIn('item_tag.tag_id', array(1, 2))
   ->groupBy('items.id')
   ->having('count(*)', '=',2)
  ;
}   
}

そしてそれを実行する

   #routes.php
   Route::get('/', function()
   {
        return Item::withTags()->get();
   });

そのタグ 1 と 2 を持つすべてのアイテムを返す必要がありますが、何も返されません!

助けはありますか?

4

3 に答える 3

4

ついに答えが見つかりました!

「havingRaw」を使用すると問題が解決します

また、「リスト」はタグテーブルからのタグのIDを提供します

注:「havingRaw」はLaravel 4-beta4以降でのみ使用できます

class Item extends Eloquent {

protected $table = 'items';

public function tags()
{
    return $this->belongsToMany('Tag');
}

public static function withTags($tags = array())
{
    $count = count($tags);
    return static::leftjoin('item_tag', 'items.id', '=', 'item_tag.item_id')
        ->whereIn('item_tag.tag_id', Tag::whereIn('name', $tags)->lists('id'))
        ->groupBy('item_tag.item_id')
        ->havingRaw('count(*)='.$count)
        ;
}    
}

そしてそれを実行するには

   return Item::withTags(['foo','bar'])->get();

更新:重要な注意

上記のコードの出力を見ると、item-> idにitems.id!が含まれておらず、代わりにtags.idが含まれていることがわかります。これは、「結合」を使用するとあいまいさが発生し、これを解決できるためです。次のselectステートメントを追加する必要があります

  ->select('items.id as id','items.name as name')
于 2013-03-23T21:24:20.110 に答える
1

内部結合を探していると思いますか?これを試して:

class Item extends Eloquent {

    protected $table = 'items';

    public function tags()
    {
        return $this->belongsToMany('Tag');
    }

    public static function withTags()
    {
        return static::join('item_tag', 'items.id', '=', 'item_tag.item_id')
            ->whereIn('item_tag.tag_id', array(1, 2));
    }   
}
于 2013-03-21T04:33:15.970 に答える
1

ManyToMany 関係の場合、両方の Eloquent クラスが を返す必要があり$this->belongsToManyます。Tag クラスでは、ピボット テーブルを使用しない hasMany を使用しています。

上記を修正すれば、ピボットテーブルに正しくアクセスできるはずです。

問題は、アイテムIDではなくタグIDに参加する必要があることだと思います。

return static::leftJoin(
    'item_tag',
    'tags.id', '=', 'item_tag.tag_id'
)
于 2013-03-20T22:29:04.017 に答える