Is there a clean way to enable certain models to be ordered by a property by default? It could work by extending the laravel's QueryBuilder, but to do so, you'll have to rewire some of it's core features - bad practice.

reason

The main point of doing this is - one of my models get's heavily reused by many others and right now you have to resort the order over and over again. Even when using a closure for this - you still have to call it. It would be much better to be able to apply a default sorting, so everyone who uses this model, and does not provide custom sorting options, will receive records sorted by the default option. Using a repository is not an option here, because it get's eager loaded.

SOLUTION

Extending the base model:

protected $orderBy;
protected $orderDirection = 'ASC';

public function scopeOrdered($query)
{
    if ($this->orderBy)
    {
        return $query->orderBy($this->orderBy, $this->orderDirection);
    }

    return $query;
}

public function scopeGetOrdered($query)
{
    return $this->scopeOrdered($query)->get();
}

In your model:

protected $orderBy = 'property';
protected $orderDirection = 'DESC';

// ordering eager loaded relation
public function anotherModel()
{
    return $this->belongsToMany('SomeModel', 'some_table')->ordered();
}

在您的控制器中:

MyModel::with('anotherModel')->getOrdered();
// or
MyModel::with('anotherModel')->ordered()->first();

推荐答案

Yes you would need to extend Eloquent to always do this as standard for any query. What's wrong with adding an order by statement to the query when you need it ordered? That is the cleanest way, ie, you dont need to 'unhack' Eloquent to get results by natural order.

MyModel::orderBy('created_at', 'asc')->get();

除此之外,最接近您需要的是在模型中创建查询范围.

public function scopeOrdered($query)
{
    return $query->orderBy('created_at', 'asc')->get();
}

然后,您可以调用ordered作为方法,而不是get来检索排序结果.

$data = MyModel::where('foo', '=', 'bar')->ordered();

如果你想在不同的模型中实现这个功能,你可以创建一个基类,然后把它扩展到你想要访问这个作用域方法的模型中.

Laravel相关问答推荐

我应该如何使用遵循依赖反转原则的工厂方法设计模式

为什么我的 Laravel 开发服务器不提供 public 文件夹下的文件?

如何让 Laravel 的 Collection 表现得像一个流?

Inertiajs - 使用链接组件添加记录但无法在不使用表单的情况下清除文本区域

使用命令行界面停止 laravel 服务器

Laravel/Eloquent:致命错误:在非对象上调用成员函数 connection()

在 laravel 5 中的表单请求验证后传递旧输入

Eager加载:在具有eloquent关系的枢轴上使用`with`

如何修复无效请求(不支持的 SSL 请求)

file_put_content ...无法打开流:Laravel 5 中的权限被拒绝

SQLSTATE [01000]:警告:1265 列的数据被截断(truncated)

如何更改 ember-cli 中的 dist 文件夹路径?

如何在 Laravel Eloquent 中 Select 某些字段?

我如何从给定的日期时间 struct 创建Carbon 对象?

测试指向外部站点的重定向链接

Laravel 无法创建根目录

Laravel assets资源与混合

Laravel:在另一个控制器中加载方法而不更改 url

Laravel X-CSRF-Token 与 POSTMAN 不匹配

Laravel 更新后用户模型错误(用户类包含 3 个抽象方法)