30

I have a controller where I want to combine data from multiple tables with parallel structures. What I want to end up with in the end is one object I can return from the controller so I can parse it in Backbone.

I want to do something like this:

public function index()
{
    $mc = MainContact::where('verified', '=', '1')->get();
    $sm = SendMessage::where('verified', '=', '1')->get();

    $obj = (object) array_merge((array) $mc, (array) $sm);
    return $obj;
}

I'm told by another post on StackOverflow that this works in PHP 5.3+. However, this returns the following error in Laravel:

UnexpectedValueException: The Response content must be a string or object implementing
 __toString(), "object" given.

How do I implement this method in Laravel? Both $mc and sm return valid objects in Laravel.

Community
  • 1
  • 1
sehummel
  • 5,476
  • 24
  • 90
  • 137

6 Answers6

52

Nowadays you can use

$new_collection = $collection->merge($other_collection).

This works in Laravel 4 and seems to handle both arrays and collections.

trm42
  • 2,536
  • 2
  • 19
  • 16
  • 1
    In my scenario, it eats up some rows after the collection merge. – Ali Gajani Mar 02 '15 at 17:46
  • Is your collection using strings as keys? Collection::merge uses PHP's array_merge, which overwrites string keys but not integer keys. If that's a problem, you can always subclass Laravel Collection to override the implementation. – trm42 Mar 03 '15 at 08:12
  • In my case, only the `$other_collection` remains and the `$collection` disappears. Why??? – Pathros Jun 06 '16 at 18:09
  • 1
    @AliGajani, yes it does. If a string key in the given items matches a string key in the original collection, the given items's value will overwrite the value in the original collection. But If the given items's keys are numeric, the values will be appended to the end of the collection. Check it out here: https://laravel.com/docs/5.7/collections#method-merge – Allan Mwesigwa Oct 04 '18 at 19:46
36

What you can do here is merge the arrays of the two query result and then use the Response with json output like shown below.

$array = array_merge($mc->toArray(), $sm->toArray());
return Response::json($array);
Raftalks
  • 2,017
  • 1
  • 21
  • 25
10

We can use collection as below

$admins = User::where('type', '=', 'admin')->get();

$authors = User::where('type', '=', 'author')->get();

$admin_author_collection = $admins->merge($authors);

Also, Please refer the various collection methods to below link

http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html

Ramesh Kotkar
  • 747
  • 9
  • 11
3
Route::get('test', function(){
    $rank = Rank::get();
    $policy = Policy::get();
    $obj = (object)array_merge_recursive((array)$rank , (array)$policy);
    var_dump($obj);
});

This is working for me. Instead of array_merge use array_merge_recursive().

Jono20201
  • 3,215
  • 3
  • 20
  • 33
Hassan Jamal
  • 694
  • 9
  • 11
0

I use concat and works for me. like this:

$role1 = User::where('role', '=', 'role1')->get();
$role2 = User::where('role', '=', 'role2')->get();
$allRoles = $role1->concat($role2);
Zahra Badri
  • 1,656
  • 1
  • 17
  • 28
-4

You could simply use array_merge(firstObject,secondObject) function.

$obj = array_merge($mc, $sm);
return $obj;
rashedcs
  • 3,588
  • 2
  • 39
  • 40