Shawn31313
Shawn31313

Reputation: 6062

Where to locate database logic in laravel?

I am currently new to laravel and I am trying to wrap my head around code structure with laravel. The reason for learning laravel is to grow my knowledge on creating good code in addition to creating an easily to manage application. For this reason, It is important to me that I am building my application to an accepted standard.

I have read several articles but am still not exactly sure where to organize things.

As of now, my application structure looks as so:

app/
    Console
    Exceptions
    Http
       Controllers
           Auth
           Message
           Settings
       Middleware
    Providers
    Traits
        Message
        Settings

One of my controller looks like something like this:

<?php

namespace App\Http\Controllers\Message;

use DB;
use Auth;
use Request;
use App\Http\Controllers\Controller;

class TypeController extends Controller
{
    public function __construct () {
        $this->middleware('auth');
        $this->middleware('access');
    }

    public function type () {
        $this->adjustTypingStatus(1);
    }

    public function untype () {
        $this->adjustTypingStatus(0);
    }

    protected function adjustTypingStatus ($level) {
        DB::table('user_lobby_info')
            ->where('userid', Auth::User()->id)
            ->where('lobby', Request::get('lobbyid'))
            ->update([ 'typing' => $level ]);
    }
}

?>

The Question

What is a better way to separate controllers into smaller, more manageable pieces? Should I put the database logic into the model and just call the model's method?

Upvotes: 3

Views: 1565

Answers (2)

Dom DaFonte
Dom DaFonte

Reputation: 1779

This is how I break down controller logic and use the Model for small to medium size projects.

1. Create your table and model

This command will create your Model and the --migration will create a migration file that references the BluePrint class that you can use to create your Model's table.

php artisan make:model UserLobbyInfo --migration

You seem to have a database already created, so you may want to remove the --migration, unless you want to use it to create schemas using BluePrint. I personally like using the migrations. Your Model will be created directly under the App folder in Laravel 5.

2. Modify your Model file

You find your Model file in the App folder. In your model you should add the fields you'll insert or update (mass fillable items) and the name of your table if it doesn't follow the Laravel convention (Laravel assumes that the camel casing indicates different words and that your table ends with an 's', so it thinks your table will be user_lobby_infos, in your case, your table name is user_lobby_info). This is how I'd update it based in your data in your query above:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class UserLobbyInfo extends Model
{
// Define mass fillable items
    protected $fillable = array('userid','lobby','typing');

//Define table
    protected $table = 'user_lobby_info';

}

How you can Use your Model

This model now has all the methods provided to it from it's extended Illuminate\Database\Eloquent\Model class, so you can do the following and more:

//To query all content:
$index = UserLobbyInfo::all();

//To query specific content:
$userLobby = UserLobbyInfo::where('id', '=', 1)->first();

//Save things:
$userLobbyInfo = UserLobbyInfo::where('id', '=', 1)->first();
$userLobbyInfo->lobby = Request::get('lobbyid')
$userLobbyInfo->save();

//Using the model for your query above this is how you can send an update:
UserLobbyInfo::where('userid', '=', Auth::User()->id)
        ->where('lobby', '=', Request::get('lobbyid'))
        ->update([ 'typing' => $level ]);

3. Creating Controller pre-canned with CRUD related methods This command will create a controller with all the methods you'd typically use in a CRUD app (Index, show, create, save, edit, update, delete)

php artisan make:controller UserLobbyController --resource

in each of these functions you'd add the respective model with the method you need.

4. Add all the routes traditionally used in a CRUD App and linked to the --resource methods If you use the --resource you will be able to use a resource function that will provide you with all the routes required for those respective resources.

Route::resource('userlobby', 'UserLobbyController');

that one line in your route file will create the following routes typical in a CRUD app run "php artisan route:list |grep userlobby" and youll see these routes:

|        | GET|HEAD  | userlobby                                | userlobby.index      | App\Http\Controllers\UserLobbyController@index                          | web                |
|        | POST      | userlobby                                | userlobby.store      | App\Http\Controllers\UserLobbyController@store                          | web                |
|        | GET|HEAD  | userlobby/create                         | userlobby.create     | App\Http\Controllers\UserLobbyController@create                         | web                |
|        | GET|HEAD  | userlobby/{userlobby}                    | userlobby.show       | App\Http\Controllers\UserLobbyController@show                           | web                |
|        | PUT|PATCH | userlobby/{userlobby}                    | userlobby.update     | App\Http\Controllers\UserLobbyController@update                         | web                |
|        | DELETE    | userlobby/{userlobby}                    | userlobby.destroy    | App\Http\Controllers\UserLobbyController@destroy                        | web                |
|        | GET|HEAD  | userlobby/{userlobby}/edit               | userlobby.edit       | App\Http\Controllers\UserLobbyController@edit                           | web                |

5. Condense your Controller to CRUD methods I will just an edit and update method below as this can get quite lengthy. Hopefully this gives you an idea on how to breakdown a controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\UserLobbyInfo;  // Add this to access your new model
use App\Http\Requests;

class UserLobbyController extends Controller
{

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $updateLobby = UserLobbyInfo::where('id', '=', $id)->first(); //This queries the table specifically for the id, just for demo purposes.

        return view('lobbies.edit', compact('updateLobby')); //This will send the above defined array to your view to pre-populate.
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $userLobby = UserLobbyInfo::where('userid', '=', Auth::User()->id)
            ->where('lobby', '=', $request->lobbyid)->first();

         //Grab the UserLobby row you want to update.
        $updateLobby->typing = $level; //update the typing value
        $updateLobby->save(); // save it.
    }

For more complex applications, I typically will migrate the heavier controller logic out to a class, and reference the class in the controller using it. I also only use DB:: class when I'm writing a complex query with multiple table joins (especially a join with multiple where clauses required in that join).

Hopefully that helps highlight how to properly use the Model in Laravel.

A lot of this info is available in the laravel documentation. I also like this cheat sheet: laravel cheat sheet

Any more questions, or if I didn't fully answer your question, just let me know.

Upvotes: 2

Alexey Mezenin
Alexey Mezenin

Reputation: 163978

Use Eloquent instead of raw SQL queries or Query Builder queries. Put all data related logic into Model classes:

public function getApprovedUsersWithPosts()
{
    return $this->where('approved', true)->with('posts')->get();
}

Your controllers should be really small. Never put queries or other logic into controllers. Also, use DI instead of facades:

protected $user;

public function __construct(User $user)
{
    $this->user = $user;
}

public function index()
{
    return view('users.approved', [
        'users' => $this->user->getApprovedUsers()
    ]);
}

Upvotes: 1

Related Questions