Laravel: Does every table need a model?

11,344

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 mix Eloquent and some Query 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.)

Share:
11,344
user3527894
Author by

user3527894

Updated on June 09, 2022

Comments

  • user3527894
    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 like getCategories() and then use the DB class like DB::table('occasion_categories')->get() to retrieve all possible categories?

  • Jarek Tkaczyk
    Jarek Tkaczyk almost 10 years
    Just a note - replace all() with get(). all is a static method that translates to non-static get and doesn't work in method chaining.
  • user3527894
    user3527894 almost 10 years
    Thanks that's what i meant.
  • Chuck Le Butt
    Chuck Le Butt over 4 years
    This 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
    Chuck Le Butt over 4 years
    Good answer. This is largely down to preference, but sometimes it's good to be reassured about your options
  • The Alpha
    The Alpha over 4 years
    @ChuckLeButt, Updated based on your comment.