Vinelab / NeoEloquent

The Neo4j OGM for Laravel
MIT License
636 stars 200 forks source link

SyntaxException: Variable not defined when using relation()->getQuery()->has() #254

Closed k98kurz closed 4 years ago

k98kurz commented 6 years ago

Introduction

I am trying to apply user-supplied search parameters to models of a hasMany relation. One of the features I wanted to have was checking of relations on the related models via the has and orHas Eloquent methods. My understanding is that calling getQuery on a relation returns an Eloquent\Builder, which should be able to handle has and orHas method calls.

Example Code

ParentModel.php

public function things()
{
    return $this->hasMany(App\Thing::class, 'THINGS');
}

Thing.php

public function parent()
{
    return $this->belongsTo(App\ParentModel::class, 'THINGS');
}

public function children()
{
    return $this->hasMany(App\Child::class, 'OFFSPRING');
}

Http/Controllers/ParentThingController.php

$things = ParentModel::find($id)->things()->getQuery()->has('children')->get();

Error Message

SyntaxException: Variable `appParentModel` not defined (line 1, column 276 (offset: 275))\n"MATCH (appParentModel:`AppParentModel`),(appParentModel)-[`rel_parent_model_thing_things`:`THINGS`]->(things:`AppThing`), (appThing:`AppThing`), (appThing)-[`rel_children_appChild`:`OFFSPRING`]->(appChild:`AppChild`) WITH appThing, count(appChild) AS appChild_count WHERE id(appParentModel) = {idappParentModel} and appChild_count >= 1 RETURN count(*)"

This error is a Neo.ClientError.Statement.SyntaxError generated by Neo4j. I have been working with Neo4j for only a couple of months and am not sure how to fix the query generation to avoid this.

Mulkave commented 6 years ago

Question: What are you trying to achieve with the getQuery then has?

k98kurz commented 6 years ago

@Mulkave the idea is to build a robust, queryable API endpoint. Example:

    $offset = request('offset', 0);
    $limit = request('limit', 50);
    $sortBy = request('sortBy', $this->defaultSortTag);
    $sortDirection = request('sortDirection', 'asc');
    $equalFields = request('equal', []);
    $notEqualFields = request('notequal', []);
    $greatedThenFields = request('greater', []);
    $lessThenFields = request('less', []);
    $likeFields = request('like', []);
    $with = request('relations', []);
    $has = request('has', []);
    $orhas = request('orhas', []);

    $query = $this->getListQuery();

    // parse search terms
    foreach($equalFields as $key => $value){
        $query = $query->where($key, $value);
    }
    foreach($notEqualFields as $key => $value){
        $query = $query->where($key, '!=', $value);
    }
    foreach($greatedThenFields as $key => $value){
        $query = $query->where($key, '>', is_numeric($value) ? intval($value) : $value);
    }
    foreach($lessThenFields as $key => $value){
        $query = $query->where($key, '<', is_numeric($value) ? intval($value) : $value);
    }
    foreach($likeFields as $key => $value){
        $query = $query->where($key, '=~', ".*$value.*");
    }
    foreach ($has as $key => $value) {
        $query = $query->has($value);
    }
    foreach ($orhas as $key => $value) {
        $query = $query->orHas($value);
    }

    $total = $query->count();

    $limit = $limit > 200 ? 200 : $limit;
    $limit = (count($has) || count($orhas) || count($with)) ? 100 : $limit;

    $results = $this->getOrderBy($query, $sortBy, $sortDirection)->offset($offset)->take($limit)->with($with)->get();
Mulkave commented 6 years ago

This is pretty old. Not sure if this is still valid or whether you were able to work it out?

If not, can you please try skipping the getQuery() call and see if any error occurs then?

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.