Laravel Eloquent 关系也可以使用宏啦 
                                                    
                        
                    
                    
  
                    
                    在 Eloquent ORM 中,如果想从一对多关系中取出一个特定值,可以通过添加一个附带特定子句的 hasOne 关系来实现。举个栗子,用户的最后一次登录记录:
class User
{
    public function logins()
    {
        return $this->hasMany(Login::class);
    }
    public function lastLogin()
    {
        return $this->hasOne(Login::class)->latest();
    }
}
看起来似乎已经很完美,除了 User 和 Login 的关系被定义了两次。在本来就容易变得琐碎的关系定义代码中,又增加了一些重复的味道。如果遇到更复杂的情况,比如取出用户的一些特定文章:点赞最多的文章、评论最多的文章、转发最多的文章、最后一次发布的文章等,重复就会在代码中蔓延开来。
对于追求优雅的 Laravel 程序员来说这怎么能忍,于是 v5.4.8 版本中合并了一个新特性:可以为 Eloquent 关系定义宏。
你只需在 AppServiceProvider 中添加如下代码:
use Illuminate\Database\Eloquent\Relations\HasOne;
//...
public function boot()
{
    HasMany::macro('toHasOne', function() {
        return new HasOne(
            $this->query,
            $this->parent,
            $this->foreignKey,
            $this->localKey
        );
    });
}
刚刚的例子可以改进为:
public function logins()
{
    // 无论你需要多少个特定的一对一关系,Login 都只出现这一次
    return $this->hasMany(Login::class);
}
public function lastLogin()
{
    return $this->logins()->latest()->toHasOne();
}
然后我们这么用:
$user = App\User::find(1);
$user->logins()->first()->id; // 1
$user->logins()->count(); // 2
$logins = $user->lastLogin->id; // 2
是不是神清气爽了许多?
翻译 https://laravel-news.com/relationship-macr... 的时候,感觉文章说的不是很清楚,就扩充了一下。
本作品采用《CC 协议》,转载必须注明作者和本文链接
                      本帖由 Summer
        于 8年前 加精
            
                
          
                    
                    
          
          
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: