62

Is there a way that I can get the current database table in use by the model that I'm in? I see that there is a table() function in Laravel/Database/Eloquent/model.php but I've been unsuccessful calling it calling it from the model that I'm in.

Chris G
  • 6,700
  • 2
  • 18
  • 20

18 Answers18

123

There is a public getTable() method defined in Eloquent\Model so you should be able to use $model->getTable().

SEYED BABAK ASHRAFI
  • 4,093
  • 4
  • 22
  • 32
Flyn San
  • 1,556
  • 2
  • 13
  • 13
68

Taylor has an answer to your question:

Within the model class you can do something like this:

return with(new static)->getTable();

If you want all your models to have the ability to return table name statically, then so something like this:

class BaseModel extends Eloquent {

    public static function getTableName()
    {
        return with(new static)->getTable();
    }

}

class User extends BaseModel {

}


User::getTableName();
Lucky Soni
  • 6,811
  • 3
  • 38
  • 57
  • 1
    For Laravel 5.3 you have to put that in Illuminate\Database\Eloquent\Model Works fine, thanks! – Santee Sep 27 '17 at 11:39
  • 23
    Do never do that @Santee. Never ever change the files inside `vendor` folder. – Tainmar Apr 18 '19 at 08:52
  • 3
    I see not benefits using `with` here. – Yevgeniy Afanasyev Jun 06 '19 at 01:45
  • @Yevgeniy Afanasyev it has benefit. I can do it in one-liner inside conroller. See my answer – poring91 Feb 05 '20 at 07:44
  • 2
    @poring91 why is it `with(new static)` better than `(new static)`? https://laravel.com/docs/5.7/helpers#method-with – Yevgeniy Afanasyev Feb 07 '20 at 04:45
  • @Yevgeniy Afanasyev I believe this since https://laravel.com/docs/5.2/helpers#miscellaneous and somehow missing in some versions, with can be used for method chaining. But, it seems there is update on newer version and when I test it, using ```with(new Class)``` and just ```(new Class)``` gives the same result. Thanks to remind me – poring91 Feb 11 '20 at 05:04
21

Edit April 2019: This answer is now out of date. See the new correct answer by Flyn San

Yes - Eloquent has a $table variable. There are two ways you can access this:

class yourModel extends Eloquent {

        public static $table = "differentTable";

        function someFunction()
        {
             return yourModel::$table;
        }
}

or

class yourModel extends Eloquent {

    public function someFunction()
    {
        return $this->table();

    }
}

then in your code

Route::get('/', function () {
    $model = new yourModel();   
    dd($model->someFunction());
});
Laurence
  • 58,936
  • 21
  • 171
  • 212
  • Thanks for the help. I've tried this with both setting the table name manually and not. I keep on getting "Using $this when not in object context". Any ideas? Thanks! – Chris G Dec 29 '12 at 14:53
  • Chris G: can you copy/paste your code here since error you are getting looks like you are calling $this inside a static method – Miro Dec 29 '12 at 22:29
  • I would think there is a getTable() function already in the eloquent model. Aside from that, it makes no sense to copy and paste the same function in children classes. If a protected property lacks a function wrapper (and in this case it does not) use a trait. – Jed Lynch Apr 25 '19 at 19:10
  • @JedLynch - this answer was in 2012, long before that function existed in Laravel. I'll edit it to be point out it's an old answer. – Laurence Apr 26 '19 at 06:12
12

In my case, i'm using laravel 5.4

return (new static)->getTable();

Jignesh Joisar
  • 13,720
  • 5
  • 57
  • 57
sh6210
  • 4,190
  • 1
  • 37
  • 27
8

It will return the table name from the model. perfectly worked on laravel 8

app(Modelname::class)->getTable()

you have to replace Modelname with your model class

Syamlal
  • 714
  • 1
  • 11
  • 20
6

Since table is a protected property in the Model class (Laravel >= 5) you will need an instance of your Model.

Here is a case example:

        DB::table( (new YourModelClassname)->getTable() )
            ->update(['field' => false]);
Lorenz Lo Sauer
  • 23,698
  • 16
  • 85
  • 87
6

You can get name of a model's table by following code:

If we have a Model as ModelName:

ModelName::query()->getQuery()->from

This method also works fine in case of custom table name that are defined by protected $table = 'custom_table_name' in the Model.

SEYED BABAK ASHRAFI
  • 4,093
  • 4
  • 22
  • 32
4

Based on Lucky Soni answer, there is another easy trick if you want to directly call it from Vontroller or View.

Tested in Laravel 6, and I keep using it, if you are "One Line Programmer" who hates extra line instance declaration. No need for extra lines in Model file too.

$string_table_name = with(new \App\Model\TableModelName)->getTable();

or better you may also be able to just call this

$string_table_name = (new \App\Model\TableModelName)->getTable();

It will return plain string of the tabel name even if you rename $table variable inside model class.

EDIT :

Minus Rep ?? Maybe you should try this first in your controller instead making new function in model class just to get table name and no need to declare the object when calling.

with() itself is Laravel helper function that returns an object of the class. and inside class that extends Model, already has function getTable(). So, you don't have to put another new redundant function inside model class. It seems the latest version, you can just call (new Class) without with() function.

The difference between this answer and Lucky's answer, mine doesn't make any new function inside Model class to get the table name, even you can just call the function inside the Controller and View without declaring the object of model class. It's for beautify the code.

While Lucky's answer create new function that inside Model class, and you need to call the function from the object.

poring91
  • 393
  • 7
  • 22
  • This seems more "Lucky Soni's answer" as opposed to "based on Lucky Soni's answer". As pointed out on his answer, what is `with()` being used for here? – Ewan Feb 10 '20 at 12:39
  • wow... -1 ? Lucky Sony put the code inside model. But my way can be just put inside controller only without adding codes inside Model class. That's the difference with more efficient line. ```with()``` is Laravel function that returns object. And getTable is predefined function inside Model class. – poring91 Feb 11 '20 at 04:45
  • `with()` allows for chaining if not otherwise possible but isn't required if the methods already return their own class instance. I'd say the -1 is because this is more of a comment than an answer? I've had the same thing happen, frustrating but it's how StackOverflow works. – Ewan Feb 11 '20 at 08:49
4

Simple way to get table name from Laravel Model by this:

$tableName = app(\App\User::class)->getTable();

Don't forget to replace:

\App\User

With Model path.

AnasSafi
  • 5,353
  • 1
  • 35
  • 38
3

Here's an other approach so that you can get a model's table name statically.

  1. Define a Trait: app/Traits/CanGetTableNameStatically.php
<?php namespace App\Traits;

trait CanGetTableNameStatically
{
    public static function tableName()
    {
        return (new static)->getTable();
    }
}
  1. Extend your required Model or BaseModel with the use statement.

app/Models/BaseModel.php

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Traits\CanGetTableNameStatically;

class BaseModel extends Model
{
    use CanGetTableNameStatically;

    // ...
}

On your models, if you set the custom table name on Laravel's reserved attribute: protected $table then it will still work & return correct table name.

app/Models/Customer.php

<?php namespace App\Models\Master;

use App\Models\BaseModel;

class Customer extends BaseModel
{
    protected $table = 'my_customers';

    // ...
}

Usage: just call YourModel::tableName() anywhere.

In Views:

{{ \App\Models\Customer::tableName() }}

When doing Joins:

DB::table( Product::tableName() . ' AS p' )
->leftJoin( ProductCategory::tableName() . ' AS pc', 'pc.id', '=', 'p.category_id')
// ... etc

Note: I use this approach where needed but full disclosure, I found another answer here that have the exact same approach, so I copy pasted here for reference of course with citation thanks to @topher

Abdul Rehman
  • 1,662
  • 3
  • 22
  • 36
2

Based on tailor Otwell's answer you could use something like this:

with(new Model)->getTable();

Note: tested on versions 5.x, 6.x, 7.x, 8.x and it works well.

Yassine Qoraiche
  • 1,077
  • 14
  • 32
2

another solution is to use the resolve helper like so:

resolve('\\App\\Models\\User')->getTable()
rasterix
  • 49
  • 3
1

None of the answers so far will get you the table name with the prefix, if you are using a table name prefix. At this time it seems like we need to concatenate the prefix with the table name ourselves if we want the real name of database table.

Here's how to get the table name including the table prefix:

echo \App\MyModel::query()->getQuery()->getGrammar()->getTablePrefix() . app(\App\MyModel::class)->getTable();
Lars Nyström
  • 5,786
  • 3
  • 32
  • 33
0

in laravel 7.x (i'm used) you can get table name with (new Target())->getTable();

$query->where('parent_id', function ($query) use ($request) {
    $query->select('id')->from((new Target())->getTable())->where('unit_id', $request->unit_id);
});

hope it's helps

0

To people who want to get table name from a Builder object instead of other object, here you are:

$conn = DB::connection("my_private_mysql_conn");
$my_builder_object = $conn->table("my_table_name");

//This will print out the table name
print $my_builder_object->from; 
Ellery Leung
  • 617
  • 3
  • 10
  • 23
0

It will work 100%. You will get table name.

    $object = new OrderStockProduct();
    // Use below line only when you have dynamic connection in laravel project
   // $object->setConnection('mysql');
    $object = $object->getTable();
    dd($object);
Kaleemullah
  • 446
  • 3
  • 8
-3

I just wanted to add the following for people coming from search engines:

In case you do not even want to instantiate the Model at all (faster?) :

$model = 'App\User';
$modelTable = str_replace('\\', '', Str::snake(Str::plural(class_basename($model))));
dd($modelTable); // will return "users"

That might look ugly but that's exactly how the getTable() method resolves it under the hood, so...

You will need to use Illuminate\Support\Str; on top of your file.

Addendum: implying you follow the framework's standards (i.e: Post model has posts table, User model has users table, etc)

Musa
  • 1,334
  • 1
  • 11
  • 21
  • 2
    This works as long as you are not overwriting the table variable to use a different table in the model. – Ludwig Dec 03 '19 at 16:26
  • 2
    I'd say this is definitely not the correct way to go about it. Assuming too much based on the model's class name is very likely to run into issues. And as pointed out by Ludwig, won't work if you're overwriting the table variable. – Ewan Feb 10 '20 at 12:23
  • You both seem to ignore the addendum. – Musa Feb 13 '20 at 00:06
-4

In Laravel 4 use static method

$table_name = Model::getTable();

or "self" inside Eloquent Model

$table_name = self::getTable();
HiTech
  • 295
  • 2
  • 7
  • 5
    It seems that the getTable() function is not static - you need an instance of the model to get the table: `$model = new Model(); $table_name = $model->getTable();` (I'm using Laravel 4.1.30). – nexus-bytes Jun 26 '14 at 03:41
  • as of 16/01/2017 I was actually able to get table's name inside the model via `self::getTable()`. Laravel 5.5. – curveball Jan 16 '18 at 20:29