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');
    }
}

我的问题:

我想获取所有具有以下两个标签“foo”和“bar”的项目?只有带有两个标签的物品才应该被退回!?

更新

我已经尝试了以下方法,但它对我不起作用,我感觉问题出在“->have”子句上,但我做错了,

假设标签“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

终于我找到了答案!

使用“haveRaw”将解决问题

“列表”也为我们提供标签表中标签的 ID

注意:“haveRaw”仅在 Laravel 4 -beta 4- 或更高版本中可用

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,这是因为使用“joins”会导致歧义,解决这个问题你必须添加以下选择语句

  ->select('items.id as id','items.name as name')
于 2013-03-23T21:24:20.110 回答
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 回答
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 回答