2

I want to merge two hasMany relations at one Model method. The two relations are nearly identical, the only difference is the foreign key.

Please note that I cannot simply call the query builders get() Method on both relations because I have to work with the merged relation, not the collection, e.g. I want to sort the merged relation later, or call ->where() on it.

Here is a sample code:

Friend.php

<?php
class Friend extends Model
{
  /*
  Database structure:
  - id
  - user_id
  - friend_id
  */

  public function user()
  {
    return $this->belongsTo('App\Models\User');
  }
  public function friend()
  {
    return $this->belongsTo('App\Models\User', 'friend_id');
  }
}

User.php

<?php
class User extends Model
{
  /*
  Database structure:
  - id
  [...]
  */

  public function friends()
  {
    $friends_left = $this->hasMany('App\Models\Friend', 'friend_id');
    $friends_right = $this->hasMany('App\Models\Friend', 'user_id');
    // return single relation
  }
}
Kaishiyoku
  • 23
  • 7
  • By definition, one Model/table has only one identifier, it looks like that Friend model would have two identifiers... is that even possible? – Amarnasan Aug 28 '15 at 09:45
  • Maybe this is helpful : http://stackoverflow.com/questions/24184069/laravel-merge-reltationships – Amarnasan Aug 28 '15 at 10:05
  • @Amarnasan yes I found that question, too, but that did not solve my problem, because there it merges two collections to one single collection meaning that I can no longer call query methods on it. – Kaishiyoku Aug 28 '15 at 10:10
  • But what kind of "query method" do you intend to perform? Can you give an example? Because I don't think you can perform a "get" after any "hasMany". I mean, you can't do this: $this->user()->get(), even if the "user()" is a standard "hasMany" relationship, because it will not return a "query" object, but a collection of object of a given model. – Amarnasan Aug 28 '15 at 10:17
  • What I currently get is an object of the type `Illuminate\Database\Query\Builder` (e.g. the variable `$friends_left` is from that type) – Kaishiyoku Aug 28 '15 at 10:21
  • @Amarnasan An example would be `$friends_merged->where('created_at', '>=', date())` – Kaishiyoku Aug 28 '15 at 10:32

1 Answers1

1

I know it's awful but... consider transforming your merged collection to a new query like this:

    $collection1 = ...;
    $collection2 = ...;
    $collection = $collection1->merge($collection2);
    $values = $collection->lists('id');
    $query = User::whereIn('id',$values)->....and continue with your queries;
Amarnasan
  • 14,939
  • 5
  • 33
  • 37
  • Well except that this solution causes another database query the performance loss won't be too high because of the primary key lookup. At least this is a low-effort workaround. – Kaishiyoku Aug 28 '15 at 13:07