0
votes

I'm currently using Laravel's fluent queries to grab data from an MSSQL DB. In order to keep using Eloquent's methods (list, sort, filter etc), I'm wrapping the fluent queries in a new collection:

return new Collection( DB::table('tblCustomerUsers')
            ->select('ContractID','ContractNum','ContractName')         
            ->where('CustomerUserID',Auth::User()->CustomerUserID)
            ->where('Restricted','0')

            ->orderBy('ContractTypeID','ASC')

            ->get()
        );  

With various wheres and joins as necessary. This all works splendidly, but as soon as I use an Eloquent method other than get, I get the following error:

Argument 1 passed to Illuminate\\Support\\Collection::__construct() must be of the type         array, object given

It seems to be something to do with the actual structure of what's being returned to the new Collection - get() or take() return an array of objects, which is fine, whereas it seems first(), for example, just returns a single object, hence the error from the Collection. Paginate() obviously returns a Paginator object, which the new Collection also has a tantrum about.

I don't want to have to remove the Collection wrapper, as I then lose the ability to use other Collection methods on the result (I'd rather not use methods like lists() in the query itself as I'm using the same set query result in different ways across the view, so I'm trying to keep it flexible, and want to keep number of queries low)

Perhaps I'm trying to have my cake and eat here, but if not, any help is appreciated!

Cheers!

1
Why would you want to create a collection when you only have a single item? - Joseph Silber
I must admit, I never actually looked at it from that perspective, and I'll probably re-visit the queries where I know to only expect one result with that in mind. That aside though, like I said, paginate is still a problem as, despite it bringing back multiple items, still returns as an object, and throws the error. - liamstuff
Why would you want to throw the paginator into a collection? If for whatever reason you do, you can always extract the items: $users = new Collection($paginator->getItems()). - Joseph Silber
Yeah I may have tied myself in knots here :) My thinking was, apply the pagination as part of the fluent query, then wrap it in the Collection. Stepping back a bit I can see why that doesn't make sense! - liamstuff

1 Answers

1
votes

You can actually use Eloquent itself:

$users = DB::table('tblCustomerUsers')
            ->select('ContractID', 'ContractNum', 'ContractName')         
            ->where('CustomerUserID', Auth::User()->CustomerUserID)
            ->where('Restricted', '0')
            ->orderBy('ContractTypeID', 'ASC')
            ->get();

$users = User::hydrate($users);

$users will now be an Eloquent Collection of Eloquent User models.


If you're only getting a single item, use this:

$user = DB::table('tblCustomerUsers')
            ->select('ContractID', 'ContractNum', 'ContractName')         
            ->where('CustomerUserID', Auth::User()->CustomerUserID)
            ->where('Restricted', '0')
            ->orderBy('ContractTypeID', 'ASC')
            ->first();

$user = (new User)->newFromBuilder($user);

$user is now a regular Eloquent User model.