【问题标题】:Laravel order by related tableLaravel 按相关表排序
【发布时间】:2016-08-19 19:24:50
【问题描述】:

我的项目中有产品和类别模型。产品属于类别。由于 Product 有外键 category_id,我可以像这样轻松地对输出进行排序:

$products = Product::orderBy('category_id', 'asc')->get();

但我真正想要的是按类别名称对产品进行排序,所以我尝试了:

$products = Product::with(['categories' => function($q){
            $q->orderBy('name', 'asc')->first();
        }]);

但这什么也没输出。作为测试,我返回了return Product::with('categories')->first();,它的输出很好......

这里是 Eloquent 关系。

产品

class Product extends Model
{
    protected $fillable = [
        'name',
        'description',
        'price',
        'category_id',
    ];

    protected $hidden = [
        'created_at',
        'updated_at',
    ];

    public function categories()
    {
        return $this->belongsTo('\App\Category', 'category_id');
    }
}

类别:

class Category extends Model
{
    protected $fillable = [
        'name'
    ];

    public function products()
    {
        return $this->hasMany('\App\Product');
    }
}

还有视图部分:

@foreach ($products as $product)
                <tr>

                    <td>{!! $product->categories->name !!}</td>
                    <td>
                        @if(!empty($product->picture))
                            Yes
                        @else
                            No
                        @endif
                    </td>
                    <td>{!! $product->name !!}</td>
                    <td>{!! $product->description !!}</td>
                    <td>{!! $product->price !!}</td>
                    <td>
                        <a href="{{ url('/product/'.$product->id.'/edit') }}">
                            <i class="fa fa-fw fa-pencil text-warning"></i>
                        </a>
                        <a href="" data-href="{{route('product.destroyMe', $product->id)}}"
                           data-toggle="modal" data-target="#confirm-delete">
                            <i class="fa fa-fw fa-times text-danger"></i>
                        </a>
                    </td>
                </tr>
            @endforeach

【问题讨论】:

    标签: php laravel sorting html-table


    【解决方案1】:

    我没有对此进行测试,但我认为这应该可以工作

    // Get all the products
    $products = \App\Product::all();
    
    // Add Closure function to the sortBy method, to sort by the name of the category
    $products->sortBy(function($product) { 
      return $product->categories()->name;
    });
    

    这也应该有效:

     $products = Product::with('categories')->get()
       ->sortBy(function($product) { 
           return $product->categories->name;
      })
    

    【讨论】:

    • 那行不通。而且没有逻辑意义。产品只能有一个类别。我已经测试了我在 Tinker 中的关系,它们可以正常工作。模型不应该是问题
    • 这是语法问题,如果产品只有一个类别,请不要将其命名为复数形式。令人困惑
    • 我以为这是约定俗成的事情?
    • 它不应该影响结果,但它只是违反了我认为一对多关系的约定
    • 更新了答案
    【解决方案2】:

    你可以使用join(),试试下面的代码

    $query = new Product; //new object
    //$query = Product::where('id','!=',0);
    $query = $query->join('categories', 'categories.id','=','products.categories.id');
    $query = $query->select('categories.name as cat_name','products.*');
    $query = $query->orderBy('cat_name','asc');
    $record = $query->get();
    

    【讨论】:

    • 为什么是新产品?我需要所有现有产品
    • 使用new你可以创建'Product'类的新对象所以如果你可以附加一些额外的where子句,你也可以用第二行替换第一行。
    • 如果有不属于任何类别的产品,请使用leftjoin而不是join
    【解决方案3】:

    您可以简单地向 Eloquent 急切加载提供函数,您可以在其中处理相关表的查询方式。

    $product = Product::with(['categories' => function ($q) {
      $q->orderBy('name', 'asc');
    }])->find($productId);
    

    【讨论】:

      【解决方案4】:

      在 laravel 中,如果不手动加入相关表,就无法按相关表执行订单,这真的很尴尬,但是这个 can package 可以为你做到这一点https://github.com/fico7489/laravel-eloquent-join

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-25
        • 2019-05-14
        • 2018-06-06
        • 1970-01-01
        • 1970-01-01
        • 2015-04-22
        相关资源
        最近更新 更多