Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lbartolic's avatar

Cannot get all objects/models from Many to Many pivot table

Hello,

I have a very confusing problem and yesterday spent whole day trying to solve it, but without success. Let's say I have tables 'items', 'users' and pivot table 'exchange_reqs'. Table 'exchange_reqs' consists of 'items' foreign_key and 2 'users' foreign keys.

When some user wants to send request for some of the items of other user, in this table I store 'user_id' (owner of the item, User model), 'requester_id' (user who has sent a request, User model) and 'item_id' (item that was requested from the user, Item model).

Now, main problem is in getting user's received requests with item data and user (requester who requested that item) data.

User.php
public function itemsRequests() {
        return $this->belongsToMany('App\Item', 'exchange_reqs', 'user_id')->withTimestamps();
    }

Item.php
public function usersRequested() {
        return $this->belongsToMany('App\User', 'exchange_reqs', 'item_id', 'requester_id')->withPivot('requester_id')->withTimestamps();
    }
testing...
User::find(15)->itemsRequests()->with('usersRequested')->get()

Last line of code returns all the items for which user received requests with all users ('requesters') who sent a request for this item. In this case problem is that each 'item' object has a "userRequested" collection with all users who requested this item, and not only the one matching the row in pivot many-to-many database. I want to have a single user who requested some item for each record from database. This causes repeating of users who requested some items through all records in collection:

Collection {#324 ▼
  #items: array:3 [▼
    0 => Item {#314 ▼
      #table: "items"
      #attributes: array:11 [▶]
      #original: array:15 [▶]
      #relations: array:2 [▼
        "pivot" => Pivot {#313 ▶}
        "usersRequested" => Collection {#331 ▼
          #items: array:2 [▼
            0 => User {#328 ▼
              #table: "users"
              #fillable: array:13 [▶]
              #hidden: array:2 [▶]
              #connection: null
              #primaryKey: "id"
              #perPage: 15
              +incrementing: true
              +timestamps: true
              #attributes: array:18 [▶]
              #original: array:22 [▶]
              #relations: array:1 [▶]
              #visible: []
              #appends: []
              #guarded: array:1 [▶]
              #dates: []
              #dateFormat: null
              #casts: []
              #touches: []
              #observables: []
              #with: []
              #morphClass: null
              +exists: true
              +wasRecentlyCreated: false
            }
            1 => User {#330 ▶}
          ]
        }
      ]
    }
    1 => Item {#315 ▶}
    2 => Item {#316 ▼
      #table: "items"
      #attributes: array:11 [▶]
      #original: array:15 [▶]
      #relations: array:2 [▼
        "pivot" => Pivot {#311 ▶}
        "usersRequested" => Collection {#321 ▼
          #items: array:2 [▶]
        }
      ]

This does not work because I get all the requested items (even with same ID, but that's okay) but for each Item model from many-to-many table I get a Collection of users who requested that item instead of getting only one user who requested that specific item from pivot table. Because of that sorting is almost impossible, data is hard to manipulate,... I know that this is because of with('usersRequested') call but I didn't know how to connect those users with requested items together other way. Furthermore, I tried collection grouping and doing other collection manipulations to filter results so I could get only 1 user (requester) for each request but without any success.

In second case, if I don't use with('usersRequested'), and use withPivot() to get extra attributes like 'requester_id', then I can get each Item from pivot table with corresponding user who requested that item but then I have just an ID value of that user -- not an object: It would be great if there was a way to make a model from withPivot () method and then pass it to collection together with other data returned from database.

Can anyone help? I just want to be able to return item requests row by row from many to many pivot table using eloquent to get Item and User models (requested item, user who sent a request). Thanks.

P.S. this is a current look of 'exchange_reqs' pivot table:

id  item_id     user_id     requester_id    timestamps...
1   11          15          1               ...
2   16          15          1               ...
3   11          15          2               ...

Getting same Items models (with the same id) in collection is preferable, but getting more of one user for each item in collection isnt. It would be great if I could just make models/objects from this table and get it for each user having user_id set in this pivot table.

0 likes
3 replies
kossa's avatar

Hello, I did not undertsnad your problem exactly, but if you want to retrieve only one user, change :

User::find(15)->itemsRequests()->with('usersRequested')->get();
// To
User::find(15)->itemsRequests()->with('usersRequested')->first(); 
lbartolic's avatar

Thank you for your reply.

However, if I use first() then I will get the same user for items with the same ID. There can be many items in pivot table with same id but with different ID's of users who requested that item. In your case for the same item that was requested from 2 users, I would get the same user for both results.

For each item in many to many pivot table I want to get user who requested that item, that is user which is in the same row like item_id in pivot table.

I hope you understand my problem.

Please or to participate in this conversation.