1

I don't understand how to access the table name within same class.

class Timesheets extends Model
{
    protected $table = "timesheets";

    public static function getAllTimesheets() {
        //return DB::table("timesheets")->get();
        return DB::table("timesheets")
            ->join('users', 'name', '=', 'users.name')
            ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
            ->get();
    }
}

How can I replace the "timesheets" with the protected Table variable?

5 Answers 5

2

Direct Answer (new static)->getTable()

class Timesheets extends Model
{
    protected $table = "timesheets";

    public static function getAllTimesheets() {
        return DB::table((new static)->getTable())
            ->join('users', 'name', '=', 'users.name')
            ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
            ->get();
    }
}

A Chance to Learn More

Eloquent Models use Magic Functions that will allow you to retrieve a new class instance's non-static methods via a static function call; Illuminate/Database/Eloquent/Model::__callStatic().

__callStatic() is triggered when invoking inaccessible methods in a static context.

Looking at the code for Illuminate/Database/Eloquent/Model::__callStatic() we see $instance = new static; which invokes Late Static Bindings. This means that the value you will get will be the same as a new class instantiation. As @PeterPan666 commented, this will only work if the requested method does not exist on the current class at all. Looking at the code for Illuminate/Database/Eloquent/Model::__call() we see that this call will be sent to a new query Builder for the model's table.

As Álvaro Guimarães answered, you can start a query for the model's table by using static::join().

class Timesheets extends Model
{
    protected $table = "timesheets";

    public static function getAllTimesheets() {
        return static::join('users', 'name', '=', 'users.name')
            ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
            ->get();
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Since getTable does exist in the Model class, PHP will not go through __callStatic. As you wrote "__callStatic() is triggered when invoking inaccessible methods in a static context." but getTable IS accessible so you'll get an exception saying that you can't call non static method like that.
@PeterPan666 You are correct. I misinterpreted the code. I am testing for a solution now and will update or delete my answer accordingly. Looking at more of the code I can see that they are using __callStatic() to essentially forward calls to a new QueryBuilder. Thank you for bringing this up.
My pleasure, but truly I can't see other solutions than the two I've pointed out...
@PeterPan666 I think the answer by Álvaro Guimarães is a valid approach. Based on how the __call() and __callStatic() are written it seems like that was the plan by Laravel.
Yeah sure but the question in the first place was "how to access protected $table". But yeah his answer is totally good.
0

You have defined getAllTimesheets as a static function.

However, static functions are associated with the class, not an instance of the class. As such, $this is not available from getAllTimesheets.

To access the $table variable, define getAllTimesheets as an instance method as

public function getAllTimesheets() { // Code // }

With this, you can access the $this variable within the function and will have access the $table variable through $this->table

Comments

0

You can't access $table like that. Though you can do something like

return DB::table((new static)->getTable())->...

Another solution is to make getAllTimesheets as a scope

public function scopeGetAllTimesheets() {
    // return DB::table($this->table)
    return DB::table($this->getTable())
        ->join('users', 'name', '=', 'users.name')
        ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
        ->get();
}

And you can call it like so

$timeSheets = Timesheets::getAllTimesheets();

I think using getTable is better because it gives you $table or the Laravel way of constructing the table name with the model.

Comments

0

Manual for PhP visibility. Protected variables are accessible within the class itself and inherited classes, so what you're trying is possible. It is called by the keyword $this. However your function is declared as static, which causes issues with $this->. Try:

 return DB::table((new static)->getTable())->...

Or simply make the function non-static by removing the static keyword.

3 Comments

For some reason $this is not working, I tried $this->table but it says $this is not defined.
Then perhaps @Max is correct, I didn't think it extending another class would have and effect on it but maybe it does...
@TMartin update your answer and and instead of $this->table (new static())
0

Use the regular static syntax:

<?php

class Timesheets extends Model
{
    protected $table = "timesheets";

    public static function getAllTimesheets() {
        return static::join('users', 'name', '=', 'users.name')
            ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
            ->get();
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.