0

Is there a built in way to return an array of standard class objects from an eloquent model instead of an eloquent collection? For example one could do:

return json_decode(json_encode(\App\User::where('status', 'active')
                ->get()->toArray()));

However this seems like unnecessary overhead since we would be converting the response to an eloquent collection, then to an array, then json encoding that array and then json decoding that string...

The reason I am after this functionality is because I am in the process of breaking apart a large enterprise application that was originally created with all business logic within controller methods (which is proving difficult to maintain). I am imposing a standard within the project that all access to the database (using eloquent models and query builder) must be performed in the service class of that particular entity, and that data returned from service classes should be of primitive php types so that if the decision ever comes down to replace eloquent with another orm or swap mysql out completely, these service classes are the only thing that would need to be rewritten to do so (kind of like a repository pattern, but not really since the service classes contain business logic as well as database access via model classes)

I suppose one solution to this could be to extend the base eloquent class to contain a method such as toObj() (probably not the best name...good thing I'm not on the standards committee ;) )

2 Answers 2

4

You can try to drop down to the Query\Builder instance on the Eloquent\Builder and get the records before models are hydrated.

\App\User::where('status', 'active')->getQuery()->get();

This returns the result that has been built up so far using Query\Builder@get directly, which returns a collection of stdClass objects, instead of Eloquent\Builder@get which will end up calling Query\Builder@get anyway to hydrate model instances.

You would have to check to make sure what is being called in Eloquent\Builder@get isn't needed for the particular query you are doing. example: Global scopes App\User::...->applyScopes()->getQuery()->get()

Sign up to request clarification or add additional context in comments.

1 Comment

Throw ->toArray() after get() and this is exactly what I'm after!
2

You can use

DB::table("user")->where("status", "active")->get()->toArray();

Using DB::table("user") instead of User:: will return a Collection of stdClass objects instead of a Collection of User models. (or single, depends on closure, ->get() vs ->first())

Just keep in mind you'll lose access to any relationships or functions as defined on the User model.

I should add that

return json_decode(json_encode(\App\User::where('status', 'active')->get()->toArray()));

Could probably be converted to

$records = \App\User::where('status', 'active')->get()
return response()->json($records);

5 Comments

I see. This could be a solution for some instances, but we do currently have code taking advantage of model relationships (from controllers not views) for example something like \App\User::find(2)->organizations()->get(). :/
In that case, you'd change the query to DB::table("organizations")->where("user_id", 2)->get(); (or use a ->join(), etc etc.) There's options to handle that.
Would your last example not return a json string whereas I'm after an array of plain old php objects? Or am I confused? (likely the case)
Oh yeah, sorry, it would return a JSON string, so you'd just wrap it in the response()... in a json_decode(). I added the edit since there's likely some interaction with the models when returning a JSON response vs just straight json_encodeing it.
There's a toJson() method on the main Model class, but unfortunately its also followed toArray() before converting to json

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.