Laravel: Does every table need a model?
Solution 1
Updated on 4th Oct, 2019:
In short, NO
, you can use Query Builder
instead of Eloquent ORM
but if you want to use Eloquent ORM
then each table has to be bound to a model
. Also, a model is not necessarily has to be an Eloquent model
, you can create a model without extending eloquent model which may or may not use database. A model doesn't mean a database access layer but... anyways, it's another big topic.
Original Answer:
Actually you need to create two Eloquent
models for both of your tables if you are using Eloquent
, for example:
class Occasion extend Eloquent {
// Laravel will look for occasions table for Occasion model so following line
// is optional if you don't want to use another table name for Occation model
protected $table = 'occasions';
// Now declare the relationship with "occasion_categories" table
public function occasionCategory()
{
// Make sure you have used occasion_categories_id as the foreugn key
return $this->belongsTo('OccasionCategory', 'occasion_categories_id', 'id');
}
}
Now create the OccasionCategory
model:
class OccasionCategory extend Eloquent {
protected $table = 'occasion_categories';
// Now declare the relationship with "occasion_categories" table
public function occasions()
{
// Make sure you have used occasion_categories_id as the foreign key
return $this->hasMany('Occasion', 'occasion_categories_id', 'id');
}
}
Now you may retrieve the occasions with it's parent occasions_category using something like this:
// Use the Occasion model
$allOccasionsWithCategory = Occasion::with('occasionCategory')->get();
// Find one Occasion whose id is 1 with OccasionCategory
$oneOccasionsWithCategory = Occasion::with('occasionCategory')->find(1);
// You may use this to get the related occasionCategory model
$occasionCategory = $oneOccasionsWithCategory->occasionCategory;
// Use the OccasionCategory model
$allOccasionsWithCategory = OccasionCategory::with('occasions')->get();
// Find one OccasionCategory whose id is 1 with Occasion
$oneOccasionsWithCategory = OccasionCategory::with('occasions')->find(1);
// You may use this to get all the related occasions model
$occasions = $oneOccasionsWithCategory->occasions;
Read more about relationship on Laravel
website.
If you use Query Builder
directly then you may use something like this (without a model):
// All occations
$occations = DB::table('occations')->get();
// All occasions and related occasion_categories
$occationsAndCategories = DB::table('occations')
->join('occasion_categories', 'occasions.occasion_category_id', '=', 'occasion_categories.id')
->get();
Read more about Query Builder on Laravel
website.
Solution 2
The laravelish way to do database is using the Query Builder or Eloquent: Laravel is a framework and it always makes sense to leverage the resources it exposes.
Laravel: Does every table need a model?
The short answer:
- No, it doesn't as long as you don't use Eloquent.
The long answer:
The Query Builder is the way to go if you still want to stick to laravel convention.
You may also use the plain old PDO: Remember Laravel is a actually a PHP framework!
My take:
It's always rewarding to be consistent:
Do it the
Eloquent
ways (Models + relationships definition) despite you can mixEloquent
and someQuery Builder
as you suggested.Doing it using
Query Builder
exclusively is also consistent and possible.
My personal preference goes to the Eloquent
option.
Solution:
WereWolf - The Alpha answer provides excellent possible solutions using both options.
Solution 3
Just wanted to chime in here with an update.
In this particular instance, I'm not sure things have changed since this was posted (could be wrong, always more to discover), but in the case of Many-to-Many relationships, the one-to-one relationship between table and model is broken, thanks to the pivot() method .
Taking from one of my own projects:
public function fees()
{
return $this->belongsToMany(Service::class)->withPivot("description");
}
In this way, you can have two models ("Fee" and "Service"), but you can access data on the intermediary table without needing a "ServiceFee" model.
In Blade:
{{ $service->pivot->description }}
At a glance, this may seem trivial, but get enough many-to-many relationships going and the number tables could even surpass the number of models. (Whether this hypothetical scenario is necessarily well-designed is a matter I am sadly lacking the time to ponder.)
user3527894
Updated on June 09, 2022Comments
-
user3527894 almost 2 years
I am building an occasion system with Laravel. I have several tables like:
- occasions
- occasion_categories (cars, trikes and other)
Now i have a model called
Occasion
which represents the table occasions, it also has a foreign key to the occasion_categories table.I want to retrieve all occasion categories, but
do i need to make a seperated model called
OccasionCategory
for the occasion_categories and define all relations in these models,or can i just make a method in the
Occasion
class likegetCategories()
and then use theDB
class likeDB::table('occasion_categories')->get()
to retrieve all possible categories?
-
Jarek Tkaczyk almost 10 yearsJust a note - replace
all()
withget()
.all
is a static method that translates to non-staticget
and doesn't work in method chaining. -
user3527894 almost 10 yearsThanks that's what i meant.
-
Chuck Le Butt over 4 yearsThis just explains the two options to the user without providing any reasoning as to which might be better or considered "best practice". Or even acknowledges the question by just saying "you can do both", there's no benefit of one way over another.
-
Chuck Le Butt over 4 yearsGood answer. This is largely down to preference, but sometimes it's good to be reassured about your options
-
The Alpha over 4 years@ChuckLeButt, Updated based on your comment.