Get ids array from related laravel model which is having belongsToMany relationship

41,491

Personally, I wouldn't change the users() relationship, but maybe add an accessor for user IDs

class Role {
    protected $fillable = ["name"];

    // adding the appends value will call the accessor in the JSON response
    protected $appends = ['user_ids'];

    public function users()
    {
         return $this->belongsToMany('App/Models/User');
    }

    public function getUserIdsAttribute()
    {
        return $this->users->pluck('user_id');
    }
}

Then you still have a working relationship, but can access the user IDs as an array in the Role response. If that doesn't work for you, as mentioned by @Creator, you could probably just add ->pluck('id') in the relationship rather than the select()

Share:
41,491
sp11
Author by

sp11

Updated on March 23, 2020

Comments

  • sp11
    sp11 about 4 years

    I have a model Role which belongs to many Users.

    Class Role {
         public $fillable = ["name"];
    
         public function users()
         {
              return $this->belongsToMany('App/Models/User')->select(['user_id']);
         }
    }
    

    When I retrieve users using with query in Role. I want It would return only user_ids array

     Role::with("users")->get();
    

    it should return the following output

     [ 
       {
         "name": "Role1",
         "users" : [1,2,3]
       },
       {
         "name": "Role2",
         "users" : [1,2,3]
       }
     ]
    

    Currently it gives following output

    [ 
       {
         "name": "Role1",
         "users" : [
            {
               user_id : 1
            },
            {
               user_id : 2
            },
    
            {
               user_id : 3
            }
       },
       {
         "name": "Role2",
         "users" : [
            {
               user_id : 1
            },
            {
               user_id : 2
            },
    
            {
               user_id : 3
            }
         ]
       }
     ]
    
  • llioor
    llioor over 6 years
    In Laravel 5.5+ I needed to do return $this->users->pluck('pivot.user_id'); or just to use the "id".
  • AndrewMcLagan
    AndrewMcLagan almost 6 years
    THIS IS SLOW - you are accessing this using $this->users->pluck() should be $this->users()->pluck('feild')->get()
  • benJ
    benJ almost 6 years
    @AndrewMcLagan erm, nope, calling $this->users() returns the query builder. Calling $this->users returns the eager-loaded collection. You could do $this->users()->pluck('field'), but that would be slower as you're repeating the query.
  • giovannipds
    giovannipds over 5 years
    here the guys used $this->users()->allRelatedIds();. Does your tip apply here too, @benJ?
  • giovannipds
    giovannipds over 5 years
    Tested both and they make different queries for me: 1) pluck seems to make this long query: select agents.*, agent_price_table.price_table_id as pivot_price_table_id, agent_price_table.agent_id as pivot_agent_id from agents inner join agent_price_table on agents.id = agent_price_table.agent_id where agent_price_table.price_table_id = 20; 2) while allRelatedIds makes a very shorten one: select agent_id from agent_price_table where price_table_id = 20. But apparently both make an additional query.
  • giovannipds
    giovannipds over 5 years
    @benJ I tried it here and apparently either way will going to make a query for each row.
  • CodeToLife
    CodeToLife over 3 years
    just a comment. Then you will cal it as $aRole->getUserIdsAttribute() not $aRole->getUserIdsAttribute