最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

laravel - Is it possible to use model attributes when creating a global scope? - Stack Overflow

programmeradmin1浏览0评论

I am trying to limit access to a particular model to only certain user groups. However, within those groups, there are certain prohibited services. I am trying to set up a global scope that will block the prohibited services.

The code I have (not working) is this.

  protected static function boot()
  {
    parent::boot();
    static::addGlobalScope('status', function (Builder $builder) {
      $builder->whereHas('groups.users', fn($q) => $q->where('user_id', Auth::user()->id))
        ->whereDoesntHave('groups.prohibitedServiceTypes', fn($q) => $q->where('service_type_id', $this->service_type_id));
    });
  }

The reason it doesn't work is that $this is not available for the global scope.

For some clarification, the model here is called encounter. An Encounter can have many groups, and a group can have many users. A group also has many prohibited service types. I want to select those records where the service_type_id is not in the current group's list of prohibitions.

In SQL, I'd write this:

SELECT * FROM encounters e 
JOIN group_encounter ge ON (e.id = ge.encounter_id) 
JOIN groups g ON (g.id=ge.group_id)
JOIN group_user gu ON (gu.group_id=g.id)
WHERE gu.user_id = <current user> AND NOT EXISTS 
   (SELECT * FROM group_prohibited_service_types WHERE service_type_id = <current service type>)

But I'm trying to do this the laravel way.

I am trying to limit access to a particular model to only certain user groups. However, within those groups, there are certain prohibited services. I am trying to set up a global scope that will block the prohibited services.

The code I have (not working) is this.

  protected static function boot()
  {
    parent::boot();
    static::addGlobalScope('status', function (Builder $builder) {
      $builder->whereHas('groups.users', fn($q) => $q->where('user_id', Auth::user()->id))
        ->whereDoesntHave('groups.prohibitedServiceTypes', fn($q) => $q->where('service_type_id', $this->service_type_id));
    });
  }

The reason it doesn't work is that $this is not available for the global scope.

For some clarification, the model here is called encounter. An Encounter can have many groups, and a group can have many users. A group also has many prohibited service types. I want to select those records where the service_type_id is not in the current group's list of prohibitions.

In SQL, I'd write this:

SELECT * FROM encounters e 
JOIN group_encounter ge ON (e.id = ge.encounter_id) 
JOIN groups g ON (g.id=ge.group_id)
JOIN group_user gu ON (gu.group_id=g.id)
WHERE gu.user_id = <current user> AND NOT EXISTS 
   (SELECT * FROM group_prohibited_service_types WHERE service_type_id = <current service type>)

But I'm trying to do this the laravel way.

Share Improve this question asked Mar 5 at 19:50 mankowitzmankowitz 2,0531 gold badge19 silver badges43 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

you can use whereColumn to compare two columns within your query:

protected static function boot()
{
    parent::boot();
    static::addGlobalScope('status', function (Builder $builder) {
      $builder->whereHas('groups.users', fn($q) => $q->where('user_id', Auth::user()->id))
        ->whereDoesntHave('groups.prohibitedServiceTypes', fn($q) =>
            $q->whereColumn('group_prohibited_service_types.service_type_id', 'encounters.service_type_id')
        );
    });
}

however you should note that Auth::user() should NOT be used in scopes or models, since it would return null for any context outside your Http\Controllers

发布评论

评论列表(0)

  1. 暂无评论