七个必知必会的 Laravel Model 小知识

2019-09-04

JiangRen Mr

当我第一次开始在 Laravel 开发时,我感觉在实现模型时有很多事情可以采用更好的方式来完成。在探索 Eloquent 模型类之后,我发现你可以用你的模型做一些有趣的事儿,这会让你感觉更加的轻松。

在这篇文章中,我会向你提供7个小提示,让每一个使用 Laravel 的人都知道应该如何充分利用你的模型。

1 首先,让我们创建模型开始

当我们通过命令行创建一个模型时,你可以指定在某个文件夹中创建这个模型。你所要做的就是在模型名称前输入你的文件夹的名称。当你的模型没有存储在默认的 app 文件夹中时,这对你很有帮助。

php artisan make:model Models/Product

此时将会在 app/Models 文件夹中创建一个 Product 模型,这样可以节省你将模型移动到符合条件的的文件夹的时间。

2 转换属性类型

$casts 属性提供了将属性强制转换为某些数据类型的方法。

protected $casts = [
    'is_published' => 'boolean'
];

is_publish 属性现在将在你访问的时候强制转换为 boolean 类型,即使它在你的数据库中存储的是 integer 。也有很多的方式将属性转换为其他的类型,例如 date 和 datetime 。

我经常会看到一个错误的行为,就是在 Blade 模版文件中将 date 和 datetime 进行格式化,就像这样: 

{{ $blog->created_at->format('Y-m-d') }}

在某些 Blade 模板文件中,你将会看到在同一个变量上进行多次的格式化。这个问题可以通过 $casts 属性来更高效的解决。

对于 date 和 datetime 的转换属性,你可以指定一下格式:

protected $casts = [
    'published_at' => 'datetime:Y-m-d',
];

这将始终会以 Y-m-d 的格式返回 published_at 属性,所以你不再需要在 Blade 模板文件中进行任何的格式化了。

3 是否可见

某些属性并不应该被包含在模型的数组或JSON表示中,例如 密码 属性。此时便是 $hidden 属性登场的时候了。

protected $hidden = [
    'password'
];

$hidden* 属性就像是属性的黑名单。或者,你也可以使用 *$visible 属性来设置属性的白名单。

protected $visible = [
    'first_name',
    'last_name'
];

当在模型中设置了 $visible* 属性时,其他的属性将会自动隐藏。这个方式就像 *$fillable 和 $guarded 属性一样。

4 访问器

有些时候你想要将多个属性合并为一个属性,或者你仅仅想要格式化属性。此时我们可以使用 Laravel 的访问器。

假设你有一个 User 模型,并且它们具有 first_name 和 last_name 属性。如果你想要展示全名的话,你可以这么做:

$this->first_name . ' ' . $this->last_name

这是一个非常天真的做法。在 Laravel 中解决这个问题的方法是使用访问器。访问器会使用以下语法在模型中定义一个方法:

get[NameOfAttribute]Attribute

一个获取全名的访问会是下面这个样子:

public function getFullNameAttribute() {
    return "{$this->first_name} {$this->last_name}";
}

要获取全名的值,你只需要像这样调用访问器即可:

$user->full_name

5 修改器

修改器 允许您对值进行操作,并在模型的 *$attributes* 属性上设置操作值。变量具有与访问器相同的语法。

public function setLastNameAttribute($value) {
    $this->attributes['last_name'] = ucfirst($value);
}

这个mutator将对姓氏应用*ucfirst *函数,并将结果存储在*$attributes*属性中。

$user->last_name = 'jones'// 结果将会是 `Jones`

6 追加值

当模型具有访问器和模型关联时,默认情况下它们不会被添加到模型的数组或JSON表示中。为此,你需要将访问器或模型关联添加到模型的 $appends 属性中。现在让我们继续使用 getFullNameAttribute 访问器的这个例子:

$appends = [
    'full_name'
];
注意:
添加到 $appends 属性的访问器是以蛇形命名法引用,即便访问器是以驼峰命名法定义的。

让我们假设 User 模型与 Blog 模型存在一对多的关系。

public function blogs() {
    return $this->hasMany(App\Blog::class);
}

要将 blogs 添加到模型中,你只需要将他们添加到 $appends 属性中即可:

$appends = [
    'full_name',
    'blogs'
];

当然,我们以可以指定添加的属性。例如,如果你仅仅需要 blog 中的 id 和 title 添加到模型中。

$appends = [
    'full_name',
    'blogs:id,title'
];

7 最后润色

当一个模型与与另一个模型存在 BelongsTo 或 BelongsToMany 关联模型的关系时,比如说 Comment 属于 Blog,在某些情况下可以有助于在更新子项数据时同时更新父级的时间戳。这个问题可以通过将关系添加到 $touches 属性中来实现。

class Comment extends Model
{
    protected $touches = ['blog'];

    public function blog()
    {
        return $this->belongsTo(App\Blog::class);
    }
}

当 Comment 模型更新时,同时也会更新 Blog 模型的 updated_at 属性。

 

本文章转载自SegmentFault。

近期开课hot

视频剪辑兴趣班

start2025/01/06 08:22 (Sydney)

DevOps项目实战班第15期

start2025/01/12 07:55 (Sydney)

IT Support 训练营01期

start2025/01/19 06:13 (Sydney)

logo

Follow Us

linkedinfacebooktwitterinstagramweiboyoutubebilibilitiktokxigua

We Accept

/image/layout/pay-paypal.png/image/layout/pay-visa.png/image/layout/pay-master-card.png/image/layout/pay-airwallex.png/image/layout/pay-alipay.png

地址

Level 10b, 144 Edward Street, Brisbane CBD(Headquarter)
Level 2, 171 La Trobe St, Melbourne VIC 3000
四川省成都市武侯区桂溪街道天府大道中段500号D5东方希望天祥广场B座45A13号
Business Hub, 155 Waymouth St, Adelaide SA 5000

Disclaimer

footer-disclaimerfooter-disclaimer

JR Academy acknowledges Traditional Owners of Country throughout Australia and recognises the continuing connection to lands, waters and communities. We pay our respect to Aboriginal and Torres Strait Islander cultures; and to Elders past and present. Aboriginal and Torres Strait Islander peoples should be aware that this website may contain images or names of people who have since passed away.

匠人学院网站上的所有内容,包括课程材料、徽标和匠人学院网站上提供的信息,均受澳大利亚政府知识产权法的保护。严禁未经授权使用、销售、分发、复制或修改。违规行为可能会导致法律诉讼。通过访问我们的网站,您同意尊重我们的知识产权。 JR Academy Pty Ltd 保留所有权利,包括专利、商标和版权。任何侵权行为都将受到法律追究。查看用户协议

© 2017-2024 JR Academy Pty Ltd. All rights reserved.

ABN 26621887572