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

sidewaysglance's avatar

Best practise for DB query builder location

I have an index method in a resource controller that uses a DB query builder, the results of which are used in a view.

Currently the DB query builder is sat in my controller, obviously this is not the place for it.

Where is best practice for this to go? Am leaning towards the model.

Do you have any advice, or is it a thumbs up to go with the model?

Thanks

0 likes
12 replies
martinbean's avatar

Do you have any advice, or is it a thumbs up to go with the model?

@rightwayround Yes. Prefer using models over raw DB expressions.

karam mustafa's avatar

Hello, you can use a separate layer such as a Respoitories Design pattern or a Service pattern.

Tray2's avatar

I place my queries in the controller, something like this

return view('book.show')
		->with([
		'book' => Book::findOrFail($id)
	]);

I try to KISS.

sidewaysglance's avatar

@martinbean, @sinnbeck, @karam mustafa - thanks for your input. The reason I am using DB query builder is because I have users that belong to organisations (many-many). In the admin section, an admin can associate a user with multiple organisations.

That page shows one long list of all organisations, sorted firstly by organisations that the user is a member of, then organisations that the user is not a member of - with a toggle to add membership. I had a long fight with eloquent to in an attempt to get the results sorted on the child relationship - but it was not fruitful, and seems like exactly the type of task best suited to a database.

My DB query looks like this:

    $usersOrgs = DB::table('organisations')
        ->leftJoin('organisation_user', 'organisations.id', '=', 'organisation_user.organisation_id')
        ->leftJoin('users', 'users.id', '=', 'organisation_user.user_id')
        ->select('users.*', 'organisations.*')
        ->where('users.id', '=', $user->id)
        ->orWhereNull('users.id')
        ->orderByRaw('-users.name DESC')
        ->orderBy('organisations.OrgName')
        ->get();

My resource route is /admin/users/{user}/organisations/{organisation}

I am most tempted to add the query to the organisations model as I think that I will be easily able to find it there in the future. I struggle to see the benefit of a separate layer as suggested by @karam mustafa - to me this is adding complexity.

Is the way I am going about this wrong in some way, am I doomed to failure / hard to maintain code like this?

Sinnbeck's avatar

@rightwayround You can still use eloquent and mix it in :)

$usersOrgs = Organisation::query()
        ->leftJoin('organisation_user', 'organisations.id', '=', 'organisation_user.organisation_id')
        ->leftJoin('users', 'users.id', '=', 'organisation_user.user_id')
        ->select('users.*', 'organisations.*')
        ->where('users.id', '=', $user->id)
        ->orWhereNull('users.id')
        ->orderByRaw('-users.name DESC')
        ->orderBy('organisations.OrgName')
       ->toBase() //if you dont want eloquent models.
        ->get();
martinbean's avatar

@rightwayround You do realise that Eloquent models just use the DB query builder under the hood, so anything you can do with DB you can do with an Eloquent model, right…?

sidewaysglance's avatar

@martinbean yes I understand that. Although I don't think that I could retrieve the models sorted in the way that I want them without resorting to Query Builder could I?

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@rightwayround sure you could in theory move that whole thing to a scope and call it using eloquent

I use eloquent for my raw queries as well. I just use toBase to get a stdClass

1 like
Sinnbeck's avatar

@rightwayround happy to help. When you get more used to eloquent you can try revisiting the code and see if it makes more sense to use eloquent relations. Maybe it does and maybe it doesn't. Relationships are brilliant, but a good old just is brilliant as well

Please or to participate in this conversation.