Larastan: Call to an undefined method `withTrashed` - SoftDeletes

Created on 19 Jul 2018  ·  48Comments  ·  Source: nunomaduro/larastan

$project = $task->project()->withTrashed()->first();

Produce:

Call to an undefined method Illuminate\Database\Eloquent\Relations\BelongsTo::withTrashed().

false positive

Most helpful comment

@antonkomarev Thanks for reporting this issue.

I need to think in a solution for this. Since those methods withTrashed, etc are local instance macros instead of global macros.

Give me some time to think.

All 48 comments

@antonkomarev Thanks for reporting this issue.

I need to think in a solution for this. Since those methods withTrashed, etc are local instance macros instead of global macros.

Give me some time to think.

Some news? Thanks

I am in holidays. I will be back on the 27 August.
On Tue 31 Jul 2018 at 10:26, Eric Lagarda notifications@github.com wrote:

Some news? Thanks


You are receiving this because you were assigned.

Reply to this email directly, view it on GitHub
https://github.com/nunomaduro/larastan/issues/40#issuecomment-409156377,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFNFVFA7kI9iWndLeqtTyHexj3ActBs_ks5uMCK6gaJpZM4VWcoy
.

@nunomaduro Hahaha enjoy then 👌🏽

@nunomaduro Could you investigate this one?

+1, we're also constantly running into this one

Hello @nunomaduro !
Could you add support for local instance macros?

@nunomaduro Do you have a theoretical plan for this?
I would implement it.

Any workaround?

Just added support to soft deletes v0.3.3. Can you folks run some tests?

Using v0.3.3:

image
Can't call it statically

image
Can't use it on a Builder

Same here

 ------ ----------------------------------------------------------------------
  Line   app/Providers/RouteServiceProvider.php
 ------ ----------------------------------------------------------------------
  33     Static call to instance method App\Models\Artwork::withTrashed().
  38     Static call to instance method App\Models\Artist::withTrashed().
  43     Static call to instance method App\Models\Location::withTrashed().
  48     Static call to instance method App\Models\Lists::withTrashed().
  53     Static call to instance method App\Models\Exhibition::withTrashed().
  58     Static call to instance method App\Models\Owner::withTrashed().
 ------ ----------------------------------------------------------------------

line#33

return \App\Models\Artwork::withTrashed()->findOrFail($id);

class Artwork extends Model implements HasMedia ... use SoftDeletes

@szepeviktor @gpressutto5 Please perform a composer update nunomaduro/larastan and test again.

Yes.
- Updating nunomaduro/larastan (v0.2.12 => v0.3.3): Loading from cache

@szepeviktor Perform a composer clear and re-run composer update.

You should test with the version v0.3.4.

:) Gone!

Only onlyTrashed() remained "undefined".

@szepeviktor I don't understood your feedback about Only onlyTrashed() remained "undefined"..

namespace Illuminate\Database\Eloquent;

class SoftDeletingScope implements Scope
{
    /**
     * All of the extensions to be added to the builder.
     *
     * @var array
     */
    protected $extensions = ['Restore', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed'];
 ------ ----------------------------------------------------------------------------------
  Line   app/Http/Filters/OwnerFilter.php
 ------ ----------------------------------------------------------------------------------
  53     Call to an undefined method Illuminate\Database\Eloquent\Builder::onlyTrashed().
 ------ ----------------------------------------------------------------------------------

@szepeviktor That's another issue. Show me the the code that you have on the app/Http/Filters/OwnerFilter.php near the line 53.

The static call errors are gone. But I can't use withTrashed() on a Builder yet. Any workaround?

 ------ -------------------------------------------------------------------------------
  Line   app/Models/Lead.php
 ------ -------------------------------------------------------------------------------
  148    Call to an undefined method Illuminate\Database\Query\Builder::withTrashed().
 ------ -------------------------------------------------------------------------------

@gpressutto5 That's another issue. Show me the code that you have on the app/Models/Lead.php near the line 148.

@nunomaduro whereNotNull returns Buider|static. That's the code:

class Lead extends Model
{
    use SoftDeletes;

...

/**
 * @param Builder $query
 *
 * @return Builder
 */
public function scopeLost(Builder $query): Builder
{
    return $query->whereNotNull('column')->withTrashed();
}

I've changed $query type to Lead, like this:

class Lead extends Model
{
    use SoftDeletes;

...

/**
 * @param Lead $query
 *
 * @return Builder
 */
public function scopeLost(Lead $query): Builder
{
    return $query->whereNotNull('column')->withTrashed();
}

Now PhpStorm knows this method does exists:
image

But I still get that error:

 ------ -------------------------------------------------------------------------------
  Line   app/Models/Lead.php
 ------ -------------------------------------------------------------------------------
  148    Call to an undefined method Illuminate\Database\Query\Builder::withTrashed().
 ------ -------------------------------------------------------------------------------
class OwnerFilter extends Filter

...

    /**
     * Filter only the trashed exhibitions.
     *
     * @param  bool|string  $value
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function trashed($value = false)
    {
        return  $value == 'true' ? $this->builder->onlyTrashed() : $this->builder;
    }
namespace App\Http\Filters;

use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;

abstract class Filter

@nunomaduro Very nice job. Thank you.
Larastan knows almost 100% of Laravel.

@szepeviktor The problem is the custom code you added. You should have @return \Illuminate\Database\Eloquent\Model instead of \Illuminate\Database\Eloquent\Builder.

@gpressutto5 You shouldn't type-hint scopes, and you should use also @return \Illuminate\Database\Eloquent\Model.

@nunomaduro So $this->builder->onlyTrashed() in the above code should return \Illuminate\Database\Eloquent\Model ?

@nunomaduro As far I see the problem is that onlyTrashed is called on $this->builder which is a \Illuminate\Database\Eloquent\Builder - so changing the return type does not seem to have anything to do with it.
Please advise.

lol, what's the point of statically analyzing if you can't typehint? 😆

Jokes apart, I don't think we shouldn't type-hint scopes, neither return \Illuminate\Database\Eloquent\Model. I'm just following the docs...

Also, how is this wrong if phpstorm knows that withTrashed() exists? Maybe the issue is that larastan doesn't understand what whereNotNull() returns: \Illuminate\Database\Query\Builder|static

I'm also having issues with withTrashed(), I'm getting the following error:

------ ---------------------------------------------------------------------------- 
  Line   app/Console/Commands/ImportRecipientsCommand.php                            
 ------ ---------------------------------------------------------------------------- 
  114    Call to an undefined method Illuminate\Database\Eloquent\Model::restore().  
 ------ ----------------------------------------------------------------------------

Here's my code:

Recipient::withTrashed()->updateOrCreate([
    // Discriminating fields
], [
    // Fields to update
])->restore();

I'm using the latest Larastan v.0.3.4

Update: Reordering method calls seems to work:

Recipient::updateOrCreate([
    // Discriminating fields
], [
    // Fields to update
])->withTrashed()->restore();

Thje above code is not returning an error. I'm guessing that Larastan is not aware of the 'full' method call chain (and what I mean by that is the higher order method calls, which seems logical to me).

Call to an undefined method Illuminate\Database\Eloquent\Model::restore().

This shows that updateOrCreate() is not saying what it returns!

I am getting the same error.

Call to an undefined method Illuminate\Database\Eloquent\Relations\BelongsTo::withTrashed().

    /**
     * An event belongs to a venue.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function venue()
    {
        return $this->belongsTo(Venue::class)->withTrashed();
    }

I am seeing this error using larastan v0.3.13

Created a new issue with relevant snippets here:

https://github.com/nunomaduro/larastan/issues/225

This issue seems be fixed since laravel/framework PR acceptd

https://github.com/laravel/framework/pull/28352

Yes.

I hope everyone agrees.

I am getting the same error.

Call to an undefined method Illuminate\Database\Eloquent\Relations\BelongsTo::withTrashed().

    /**
     * An event belongs to a venue.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function venue()
    {
        return $this->belongsTo(Venue::class)->withTrashed();
    }

Same here using default SoftDeletes trait on Laravel v5.8.34. Can these errors be resolved somehow?

same error here

Laravel v5.8.35

  82     Call to an undefined method Illuminate\Database\Eloquent\Builder::onlyTrashed().

the code is

    public static function cleanUp(Builder $query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

same error here

Laravel v5.8.35

  82     Call to an undefined method Illuminate\Database\Eloquent\Builder::onlyTrashed().

the code is

    public static function cleanUp(Builder $query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

Is the Model you referenced by the cleanUp, used the SoftDeletes trait?

same error here

Laravel v5.8.35

  82     Call to an undefined method Illuminate\Database\Eloquent\Builder::onlyTrashed().

the code is

    public static function cleanUp(Builder $query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

Is the Model you referenced by the cleanUp, used the SoftDeletes trait?

yes

same error here

Laravel v5.8.35

  82     Call to an undefined method Illuminate\Database\Eloquent\Builder::onlyTrashed().

the code is

    public static function cleanUp(Builder $query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

Is the Model you referenced by the cleanUp, used the SoftDeletes trait?

yes

function cleanUp(Builder $query)

Typehint in your code caused this issue, because laravel query builder or eloquent builder does not use SoftDeletes trait default (It actually works is just because query builder defines a __call magic. to execute through to Your Model class which used the trait),
Please try another way to hint instead:

    /**
     * @param Builder|\Illuminate\Database\Eloquent\SoftDeletes $query 查询对象
     */
    public static function cleanUp($query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }
     * @param Builder|\Illuminate\Database\Eloquent\SoftDeletes $query 查询对象

thanks for response.

it occurred another error

  80     Parameter $query of method App\YouzanPush::cleanUp() has invalid typehint type Illuminate\Database\Eloquent\SoftDeletes.
     * @param Builder|\Illuminate\Database\Eloquent\SoftDeletes $query 查询对象
     */
    public static function cleanUp($query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

Trait cannot be a parameter typehint.

On Wed, 18 Sep 2019 at 03:05, Bole Chen notifications@github.com wrote:

 * @param Builder|\Illuminate\Database\Eloquent\SoftDeletes $query 查询对象

thanks for response.

it occurred another error

80 Parameter $query of method App\YouzanPush::cleanUp() has invalid typehint type Illuminate\Database\EloquentSoftDeletes.

 * @param Builder|\Illuminate\Database\Eloquent\SoftDeletes $query 查询对象
 */
public static function cleanUp($query): Builder
{
    return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
}


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/nunomaduro/larastan/issues/40?email_source=notifications&email_token=AAAZTOCOOYTXNN72WEWCH6LQKF5GVA5CNFSM4FKZZIZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD66OXSA#issuecomment-532474824,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAZTOHFGFIMF4BQNTGP473QKF5GVANCNFSM4FKZZIZA
.

>

Ondřej Mirtes

@ondrejmirtes Okay. I see.

@bolechen Please try this instead

    /**
     * @param Builder|\App\YourModel $query 查询对象
     */
    public static function cleanUp($query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

Remember to place real model class for the \App\YourModel.

@ondrejmirtes Okay. I see.

@bolechen Please try this instead

    /**
     * @param Builder|\App\YourModel $query 查询对象
     */
    public static function cleanUp($query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

Remember to place real model class for the \App\YourModel.

     * @param Builder|\App\YouzanPush $query
     */
    public static function cleanUp($query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

the error is

82 Method App\YouzanPush::cleanUp() should return Illuminate\Database\Eloquent\Builder but returns App\YouzanPush.

@ondrejmirtes Okay. I see.
@bolechen Please try this instead

    /**
     * @param Builder|\App\YourModel $query 查询对象
     */
    public static function cleanUp($query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

Remember to place real model class for the \App\YourModel.

     * @param Builder|\App\YouzanPush $query
     */
    public static function cleanUp($query): Builder
    {
        return $query->onlyTrashed()->where('deleted_at', '<', Carbon::now()->subMonth());
    }

the error is

82 Method App\YouzanPush::cleanUp() should return Illuminate\Database\Eloquent\Builder but returns App\YouzanPush.

Now you need to update your codes which calling the App\YouzanPush::cleanUp(), their return annotations, to be type Builder|\App\YourModel

Guys I found the answer for me, I had the same issue because I changed __construct() method in my model, but forgot to put parent::__construct(); in the beginning of this method

Was this page helpful?
0 / 5 - 0 ratings