Skip to content

Instantly share code, notes, and snippets.

@lukecurtis93
Created February 25, 2019 12:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukecurtis93/086d86463930cbac37459712b77da0b8 to your computer and use it in GitHub Desktop.
Save lukecurtis93/086d86463930cbac37459712b77da0b8 to your computer and use it in GitHub Desktop.
Laravel Full Text Search with JSON, using spatie schemaless attributes and query builder
<?php
namespace App\Filters\Sorts;
use Spatie\QueryBuilder\Sorts\Sort;
use Illuminate\Database\Eloquent\Builder;
class AddressSort implements Sort
{
public function __invoke(Builder $query, string $property) : Builder
{
return $query->orderBy('extra_attributes->address->street_number', 'desc');
}
}
<?php
namespace App\Filters\Location;
use Spatie\QueryBuilder\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
class FiltersLocation implements Filter
{
public function __invoke(Builder $query, $value, string $property) : Builder
{
return $query->whereLike([
'name',
'email',
'extra_attributes->address'
], $value);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\SchemalessAttributes\SchemalessAttributes;
class Location extends Model
{
use SoftDeletes;
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'description',
'email',
'extra_attributes',
'lat',
'user_id',
'lng',
];
public $casts = [
'extra_attributes' => 'array',
];
public function getExtraAttributesAttribute(): SchemalessAttributes
{
return SchemalessAttributes::createForModel($this, 'extra_attributes');
}
public function scopeWithExtraAttributes(): Builder
{
return SchemalessAttributes::scopeWithSchemalessAttributes('extra_attributes');
}
public function getAddressAttribute() {
return $this->extra_attributes->get('address')
? ($this->extra_attributes->get('address.street_number')
? $this->extra_attributes->get('address.street_number')." "
: "").
($this->extra_attributes->get('address.route')
? $this->extra_attributes->get('address.route')." "
: "").
($this->extra_attributes->get('address.locality')
? $this->extra_attributes->get('address.locality')." "
: "").
($this->extra_attributes->get('address.postal_code') ?? "")
: null;
}
}
<?php
namespace App\Http\Controllers\Api\v1\Auth;
use App\Models\Location;
use Illuminate\Http\Request;
use Spatie\QueryBuilder\Filter;
use Spatie\QueryBuilder\Sort;
use App\Http\Controllers\Controller;
use App\Filters\Sorts\AddressSort;
use Spatie\QueryBuilder\QueryBuilder;
use App\Filters\Location\FiltersLocation;
class LocationController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
return QueryBuilder::for(\Auth::user()->locations()->getQuery())
->allowedSorts('email', 'name', Sort::custom('address', AddressSort::class))
->allowedIncludes('customers')
->allowedAppends('customer_count', 'address')
->allowedFilters([
Filter::custom('where_like', FiltersLocation::class),
])
->paginate(15);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment