Eloquent ORM 实例教程 —— 查询作用域和模型事件

1、查询作用域
Eloquent还支持将一些常用的查询封装到模型方法中,方便调用,我们将其称之为“查询作用域”,实现查询作用域很简单,只需要在模型方法前加上scope前缀即可,比如我们经常需要获取浏览数最高的文章,就可以使用该机制实现——在
Post
中定义一个
scopePopular
方法:
public function scopePopular($query)
{
return $query->where('views','>=',100);
}
对应的,我们在控制器中定义测试代码如下:
$posts = Post::popular()->orderBy('views','desc')->get();
foreach ($posts as $post) {
echo '<'.$post->title.'> '.$post->views.'views<br>';
}
在浏览器中访问
http://laravel.app:8000/test
,输出如下:
<test 3> 800views
<test 2> 500views
<test 1 title> 100views
此外,查询作用域还支持动态传入参数,为了测试该方法我们为
posts
新增一个
status
字段:

同时在模型类中新增一个
scopeStatus
方法:
public function scopeStatus($query,$status=1)
{
return $query->where('status',$status);
}
接下来测试下该方法:
$posts = Post::popular()->status(1)->orderBy('views','desc')->get();
foreach ($posts as $post) {
echo '<'.$post->title.'> '.$post->views.'views<br>';
}
对应输出如下:
<test 3> 800views
<test 2> 500views
2、模型事件
Eloquent也支持模型事件——当模型被创建、更新或删除的时候触发相应事件,Eloquent目前支持八种事件类型:
creating
、
created
、
updating
、
updated
、
saving
、
saved
、
deleting
、
deleted
。
deleting
和
deleted
很好理解,在删除模型时触发,
deleting
在删除操作前执行,
deleted
在删除完成后执行。
当创建模型时,依次执行
saving
、
creating
、
created
和
saved
,同理在更新模型时依次执行
saving
、
updating
、
updated
和
saved
。无论是使用批量赋值(
create
/
update
)还是直接调用
save
方法,都会触发对应事件(前提是注册了相应的模型事件)。
你可以在任何你喜欢的地方注册模型事件,这里我们选择在服务提供者
AppServiceProvider
的
boot
方法中注册:
Post::saving(function($post){
echo 'saving event is fired<br>';
});
Post::creating(function($post){
echo 'creating event is fired<br>';
});
Post::created(function($post){
echo 'created event is fired<br>';
});
Post::saved(function($post){
echo 'saved event is fired<br>';
});
然后在控制器中编写测试代码如下:
$data = array(
'title'=>'test model event',
'content'=>'test content',
'cat_id'=>1,
);
$post = Post::create($data);
if(!$post->exists){
echo '添加文章失败!';exit();
}
echo '<'.$post->title.'>保存成功!';
接下来在浏览中访问
http://laravel.app:8000/test
,页面输入如下:
saving event is fired
creating event is fired
created event is fired
saved event is fired
<test model event>保存成功!
需要注意的是如果
saving
/
creating
/
updating
/
deleting
事件返回
false
,则相应的创建/更新/删除操作会退出,不再往下执行,比如我们修改上述
creating
事件代码如下:
Post::creating(function($post){
echo 'creating event is fired<br>';
if($post->cat_id==1)
return false;
});
也就是当文章分类id等于1的时候,不再往下执行,在浏览器中再次访问
http://laravel.app:8000/test
,页面输出如下:
saving event is fired
creating event is fired
添加文章失败!
有了模型事件之后,我们就很方便地在模型创建、更新或删除的不同生命周期阶段添加相应的业务逻辑。
17 Comments
XXX::where('id', x)->updata(array());
这样用的,这个update方法实际上是Builder里的update方法