使用Laravel 5,如何通过pivot表获取所有()和belongsToMany关系的order

时间:2016-06-03 21:25:48

标签: laravel

我有优惠和常见问题解答。我有功能关系,我可以参考$ deal-> faqs()并返回正确的常见问题解答。

当我管理与交易相关的常见问题时,我试图解决的问题出现了。在我的交易管理员视图(新/编辑)中,我得到了所有常见问题解答。

$faqs = \App\Faq::all();    

这很好用,我甚至可以通过我的复选框检查faq是否与交易有关:在视图中:

{!! Form::checkbox('faqlist[]', $faq->id, $deal->faqs->contains($faq->id) ? true : false) !!} 

所以现在我们有一个所有常见问题列表,并检查正确的那些。

我在数据透视表(deal_faq)上设置了一个订单列。该表包括:

  • DEAL_ID
  • faq_id
  • 时间戳
  • 顺序

在我的表单中,我有一个拖放订购解决方案(js)构建和工作。通过工作我的意思是,我可以拖放,隐藏字段值更新,以反映正确的顺序。

创建交易时,这没问题。获取所有常见问题解答,检查几个关联,拖动到订单,然后保存。

编辑交易时,我需要根据deal_faq表中的订单栏加载。这是我的问题。

我尝试了一些但总是出错。我尝试过的一个例子是:

$faqs = \App\Faq::orderBy('deal_faq.order', 'asc')->get();

这会返回错误:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'deal_faq.order' in 'order clause' (SQL: select * from `faq` order by `deal_faq`.`order` asc)

我认为问题在于我正在尝试获取所有内容,但是由于订单字段位于deal_faq上,因此仅针对相关常见问题存在的字段进行排序。只是不确定如何解决。

1 个答案:

答案 0 :(得分:0)

实质上,您需要加入数据透视表,然后应用订单

$faqs = \App\Faq::join('deal_faq', 'faqs.id', '=', 'deal_faq.faq_id')
    ->orderBy('deal_faq.order', 'asc')
    ->get();

您可能需要调整表名和列名以匹配您的架构。

现在,您可以将此逻辑提取到Faq模型

的范围内
class Faq extends Model
{
    ...

    public function scopeOrdered($query)
    {
        return $query->join('deal_faq', 'faqs.id', '=', 'deal_faq.faq_id')
            ->orderBy('deal_faq.order', 'asc');
    }
}

然后像这样使用它

$faqs = \App\Faq::ordered()->get();

<强>更新

  

这可以按顺序获取常见问题解答,但它只能得到那些   已被关联。将会有与之无关的常见问题解答   因此没有订购。

在这种情况下,您只需使用outer join - LEFT JOIN即可。范围定义将如下所示

public function scopeOrdered($query)
{
    return $query->join('deal_faq', 'faqs.id', '=', 'deal_faq.faq_id', 'left')
        ->orderBy('deal_faq.order', 'asc');
}

或更具表现力

public function scopeOrdered($query)
{
    return $query->leftJoin('deal_faq', 'faqs.id', '=', 'deal_faq.faq_id')
        ->orderBy('deal_faq.order', 'asc');
}

请考虑添加二级订单(即通过id或faqs表中有意义的任何其他字段)。这样,无论您是否在数据透视表中定义了明确的顺序,每次都会有一个确定性排序的结果集。