范围和关系不能一起工作 - Laravel

Scope and Relation doesn't work together - Laravel

用户模型

    class User extends Authenticatable
    {
        use HasApiTokens,HasFactory, Notifiable;
        
        protected $table = "users";
        protected $primaryKey = 'ID';
    
        public function scopeActive($query)
        {
            return $query->where('activated', 1);
        }

        public function followings()
        {
        return $this->hasMany('App\Models\Contacts','user_id','ID')->active();
        }

联系人模型

class Contacts extends Model
{
    use HasFactory;

    protected $table = "contacts";
    protected $primaryKey = 'ID';

    public function user()
    {
        return $this->belongsTo(User::class, 'user_id', 'ID');
    }

当我在 Tinker 上调用 User::find(1)->followings()->count() 时,我得到

BadMethodCallException with message 'Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::active()'

我怎样才能得到只有 activated = 1 的关注者?

Laravel 模型有一个名为 query 的 属性。

此 属性 在您为模型调用查询时自动使用 这两个语句完全相同:

User::query()->where('id',1)->get();
User::where('id',1)->get();

当您直接或间接调用 query() 时,Laravel 在此 line

中注册作用域

当你使用 $this->hasMany('App\Models\Contacts','user_id','ID') 时,结果将来自 class HasMany 而这个 class 没有名为 active() 的方法,这就是为什么你看到这个错误。

要修复它,您必须在使用用户模型查询时应用范围:

$result=User::query()->activated()->with('followings')->findOrFail(1);

如果您希望使用范围的激活用户的以下计数,您应该将此范围应用于以下模型:

public function scopeHasActivedUser($query)
{
    return $query->whereHas('user', function($query)
              {
                 $query->where('users.activated', 1);
              });
        }

在控制器中:

$fllowingsCountForActivatedUser=Fllowing::query()->hasActivedUser()->count();

如果我是你,我会这样得到结果:

$user=User::withCount(['followings'=>function($query){
$query->where('users.activated', 1)})])->find(1);

现在 $user 模型实例应该有一个名为 'followings_count' 的 属性 用于唯一激活的关注者计数

我通过向联系人模型添加自定义范围来修复它

public function scopeActiveFollowings($query)
    {
        return $query->join('users', function($join)
            {
                $join->on('users.ID', '=', 'contacts.contact_id')
                    ->where('activated', '=', 1);
            });
    }