Basic overview of how to query a database and display results in laravel
I'm having a very difficult time understanding the various ways Laravel interacts with databases. I have an existing database, and as an exercise I just want to query the records from one table and display them on a page. However, I'm lost in all the different terminology and tools mentioned in the various articles and tutorials online: migrations, models, eloquent, query builder etc.
For the sake of my own understanding, can someone explain, or link to an article, that explains the simplest method to query a table and display the results on a page?
Just skip migrations/seeding part, if you have a current database just create your model, use routes or controller and set a view and that's it.
Thanks for the reply, I'll check that out. For my understanding though, If I have a DB that currently only has one table so there are no relationships to define, are the models required?
The models encapsulate your entities, which are the tables in your database. If you want to take advantage of Eloquent (models) and everything it offers, even if not using relationships, you still need to define some kind of class in order to interact with the table. This may be as simple as:
<?php
class YourTable extends Eloquent {
protected $table = "your_table"; // only required if your table name doesn't follow Eloquent naming
}
If you don't want to use Eloquent, you can always make use of the DB class and it's query building capabilities directly.
With Laravel, assuming you have an existing database you would (very basic steps):
- setup your DB connection in Laravel's config's database.php
- create a model // search model on Laracasts
- configure the model to connect to your DB
- create a Controller
- create a route in route.php to connect to your Controller
- have your controller write to a model
Nolan
Thanks for all the responses. I continue to have trouble with this. If I could just see one functioning query I'm sure it would all fall in place for me. I have created a simple model:
class Towns extends Eloquent {
protected $table = "town_export";
}
In the tutorial mentioned above, it states that I will only need a route and a view file for a basic demo.
Route:
Route::get('towns', function() {
return View::make('towns')->with('town_list', Towns::all());
});
In that example I am simply trying to return all records in the town_export table.
View:
some HTML
{{ $town_list }}
more HTML
I'm getting an error with this. Before I get into posting specific errors, is this overall scheme correct?
Not yet. Almost there. Your route should be after the function:
$townList = Town::all();
return View::make('town')->with('townList', $townList);
Because you are getting an object with many results your view:
@foreach($townList as $town)
{{ $town->name }} or what the column name is
@endforeach
Laravel 4 https://laracasts.com/series/laravel-from-scratch/episodes/6
Laravel 5 https://laracasts.com/series/laravel-5-fundamentals/episodes/9
// Post.php
class Post extends Eloquent {
}
// PostsController.php
class PostsController extends BaseController {
public function index()
{
$posts = Posts:all();
return View::make('posts.index', compact('posts'));
}
}
// routes.php
Route::get('posts', 'PostsController@index');
// posts/index.blade.php
<ul>
@foreach($posts as $post)
<li>{{ $post->body }}</li>
@endforeach
</ul>
@Ditchmonkey My advice to each and everyone interested in learning how Eloquent, and DB in general, works in Laravel, is to drop the browser! ;)
There's brilliant tool that ships with laravel out of the box - apart from Symfonys console, there's an interactive shell Boris:
~/my-project/ $ php artisan tinker
[1] >
// wooo hoo, we are now in the Laravel application environment, with all of its features!
// so let's make use of it:
[1] > $users = User::where('id', '>', 5)->get();
// object(Illuminate\Database\Eloquent\Collection)(
//
// )
[2] > $users->count();
// 687
[3] > DB::getQueryLog();
// array(
// 0 => array(
// 'query' => 'select * from `prefix_users` where `prefix_users`.`deleted_at` is null and `id` > ?',
// 'bindings' => array(
// 0 => 5
// ),
// 'time' => 58.119999999999997
// )
// )
[4] >
This is by far the best way to learn the framework, especially Eloquent/DB. The only thing missing is whole routing layer, because, obviously, we're not calling the controllers. However we can test anything that goes into the controllers with no effort.
It provides instant feedback, so instead of editing your controller, switching to the browser, refreshing, waiting for the exception or a result, you can just type the query and work with the result straight away.
For those who don't know the tool, it's a REPL
The error I get is at
$townList = Town::all();
\Component\Debug\Exception\FatalErrorException …/app/routes.php64
So i'm wondering if my issue is in the db connection. How can I test this?
@Ditchmonkey No. Check the stacktrace details, you'll find the issue there. Or paste it otherwise.
The error is:
Class 'Towns' not found
Does that mean there is something wrong with my model?
I suppose your model is called Town. Also, it might be in a namespace like App\Models\Town, so check on that.
Yeah app/models/Towns.php exists and looks like
Towns extends Eloquent {
protected $table = "towns_export";
}
I'm wondering if my default database does not have some required column names for Laravel so I need additional info on my Model? If this is the case, shouldn't the stacktrace indicate a problem in my models file?
I really appreciate all the help and sorry for being so dense about this.
I will gladly help you, but let me do that. I mean show the code that you execute and causes the error and paste the stacktrace as well, otherwise it's just guessing..
The "stack frame" says "no comments for this stack frame" so I'm assuming there is no detail for the trace?
I'm really lost here. Id be happy to pay you to login to my server and give me a few pointers. If interested please let me know how to contact you.
Rename the class and filename to Town, then use Town::all()
// app/models/Town.php
Town extends Eloquent {
protected $table = "towns_export";
}
// app/routes.php
Route::get('towns', function()
{
return View::make('towns')->with('town_list', Town::all());
});
// app/views/towns.blade.php
@foreach($town_list as $town)
{{ $town->whateverColumnYouNeed }}
@endforeach
I figured it out.
First, I want to thank everyone for your help you are great!
Drum roll please...........
I forgot an opening PHP tag in my models file :\
I have a follow up question related to this issue. I was able to query all records from the table and display them in a view. However when I tried to query just one record and display that in a view, I get an error. The strange thing is that querying the single record works fine in the route, but when I try display that single record in the view I get an error. This works:
Route::get('dbtest', function() {
$TownResults = Town::find(38078);
return $TownResults;
});
but this does not:
Route::get('towns', function() {
//$TownResults = Town::all();
$TownResults = Town::find(38078);
return View::make('towns')->with('town_list', $TownResults);
});
Note that the commented line where all records are being queried does work. My view looks like:
@extends('layouts.wmh_main')
@foreach($town_list as $town)
{{ $town->title }}
@endforeach
I can't see why the view would break when the only difference is the number of results returned from the query. The error I get is "Trying to get property of non-object (View: /home/ditchmon/public_html/laravel/cats/app/views/towns.blade.php) "
When you query a single row you don't use a for each loop. In your view for a single row just use the variable you pass.
{{ $TownResults->title }} is all that's needed.
@jekinney thanks that was it. Isn't this undesirable behavior? Why would the app require that I update the code in a view based on whether a query returns one result or more than one result? Also, what if the table being queried had some records removed and ended up with a single row, wouldn't the app then be broken?
@Ditchmonkey You made it so.
Check this:
Model::find($id) / Model::first() / Model::finrOrFail($id)
all these methods return single Eloquent\Model (or null / throw exception).
Now:
Model::get()
Always returns Eloquent\Collection, even if there is one, or even no rows at all. So if you want to use foreach, then don't fetch using find, but rather get. Then you can be sure nothing will break, no matter how many rows you got.
Please or to participate in this conversation.