Reputation: 6062
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
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
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