Laravel Recursive Relationships

后端 未结 7 2016
醉梦人生
醉梦人生 2020-11-28 21:22

I\'m working on a project in Laravel. I have an Account model that can have a parent or can have children, so I have my model set up like so:

public         


        
7条回答
  •  -上瘾入骨i
    2020-11-28 21:43

    I think I've come up with a decent solution as well.

    class Organization extends Model
    {
        public function customers()
        {
            return $this->hasMany(Customer::class, 'orgUid', 'orgUid');
        }
    
        public function childOrganizations()
        {
            return $this->hasMany(Organization::class, 'parentOrgUid', 'orgUid');
        }
    
        static function addIdToQuery($query, $org)
        {
            $query = $query->orWhere('id', $org->id);
            foreach ($org->childOrganizations as $org)
            {
                $query = Organization::addIdToQuery($query, $org);
            }
            return $query;
        }
    
        public function recursiveChildOrganizations()
        {
            $query = $this->childOrganizations();
            $query = Organization::addIdToQuery($query, $this);
            return $query;
        }
    
        public function recursiveCustomers()
        {
             $query = $this->customers();
             $childOrgUids = $this->recursiveChildOrganizations()->pluck('orgUid');
             return $query->orWhereIn('orgUid', $childOrgUids);
        }
    
    }
    

    Basically, I'm starting with a query builder relationship and adding orWhere conditions to it. In the case of finding all of the child organizations, I use a recursive function to drill down through the relationships.

    Once I have the recursiveChildOrganizations relationship, I've run the only recursive function needed. All of the other relationships (I've shown recursiveCustomers but you could have many) use this.

    I avoid instantiating the objects at every possible turn, since the query builder is so much faster than creating models and working with collections.

    This is much faster than building a collection and recursively pushing members to it (which was my first solution), and since each method returns a query builder and not a collection, it stacks wonderfully with scopes or any other conditions you want to use.

提交回复
热议问题