3

I want to use the different queries inside one method and I want to pass a part of query inside that.

My method looks like this:

static function methodName($partOfQuery)
{
   ModelName::where('...')->$partOfQuery->...;
}

And I want to do something like:

$partOfQuery = where('columnName', '>=', 5)->whereRaw('Other Condition');
self::methodName($partOfQuery);

But I was faced with this error: Call to undefined function App\Classes\ClassName\where()

Anyone could help me with this issue? Thanks

2
  • laravel.com/docs/8.x/eloquent#local-scopes Commented Jan 10, 2022 at 13:44
  • I think your question lacks information. Where do you want to use methodName method? It appears that you want to use the method inside the modoel class itself Commented Jan 12, 2022 at 10:38

3 Answers 3

3

I think that the error is because where is called without an eloquent model class.

Something you can do with query builder is to call a function inside your where condition like:

SomeModel::where(function($query){
// do something
$query->where(...)
})
Sign up to request clarification or add additional context in comments.

Comments

2

I doubt there is nothing exactly like what you described. But there are alternatives, if I understand correctly, you are trying to chain multiple methods.

If so, you can do the following:

In your model class:

static function getActiveBooks()
{
    return self::where('status', 'active');
}
public function getFeaturedBooks() {
    return $this->getActiveBooks()->where('featured', 'active');
}

Usage:

$activeBooks = (new Book())->getFeaturedBooks()->get();

There are multiple ways, you can also use scope as @levi described in the comment section , they are 2 sides of the same coin.

1 Comment

@huy-pham Thanks, now I am doing something like your answer. But I have a lot of methods and all of these methods send parameters to the final method. I wanted to pass just a query not an object of a model. BTW, Thanks.
0

I realise this is quite old, but thought this might help others who come across this question.

It might be better to refactor so that the partial query is added to an existing query via a method.

$query = ModelName::where('...');
$query = addPartOfQuery($query);
/* continue doing whatever else you need to do with the query, for example */
$models = $query->get();

The addPartOfQuery() method would then be something like this:

function addPartOfQuery($query) {
    return $query->where('columnName', '>=', 5)->whereRaw('Other Condition');
}

Another possible approach would be to use a local scope in a trait that can be used by all models that need it.

trait PartOfQuery {
    public function scopePartOfQuery(Builder $query): void {
        $query->where('columnName', '>=', 5)->whereRaw('Other Condition');
    }
}

In each model class that needs to use the partial query, you would need to use the trait.

class ModelName {
    use PartOfQuery;
...
}

Your queries could then be written like this.

ModelName::partOfQuery()->where('...');

The trait approach only works if the partial query is always the same, regardless of the model. Otherwise, you could just add a separate scopes in each model, or use the first approach and add logic and additional parameters to the addPartOfQuery() method to handle any model-specific requirements.

To read more on local scopes, see https://laravel.com/docs/10.x/eloquent#local-scopes.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.