0

I'm new to Laravel and have some understanding problems how can I implement a search function to my app.

What I have tried so far.

I created a model that gets the data from the db (this is working)

class Post extends Model
{
    public static function scopeSearch($query, $searchTerm)
    {
        return $query->where('city', 'like', '%' .$searchTerm. '%')
                     ->orWhere('name', 'like', '%' .$searchTerm. '%');
    }
}

My controller looks like this:

use App\Post;

    class PostsController extends Controller
    {
        public function index(Request $request) 
        {
            $searchTerm = $request->input('searchTerm');
            $posts = Post::all()
            ->search($searchTerm);
            return view('posts.index', compact('posts', 'searchTerm'));
        }

       public function show($id)
       {
           $post = Post::find($id);
           return view('posts.show', compact('post'));
       }
    }

With php artisan tinker the model is working. I'm getting the db query.

On the front-end I have a simple input field with a submit button:

<div class="container">
    <div class="col-sm-8">
        <form action="posts.index" method="GET">
            {{csrf_field()}}
            <div class="input-group">
                <input type="text" class="form-control" name="searchTerm" placeholder="Search for..." value="{{ isset($searchTerm) ? $searchTerm : '' }}">
                <span class="input-group-btn">
                    <button class="btn btn-secondary" type="submit">Search</button>
                </span>
            </div>
        </form>
    </div>
</div>

But, now, how can I retrieve the data from the controller if I input something in the search input field? The code is only working when I get all the posts. I need to include somehow the serachTerm from the controller

@extends('layouts.master')

@section('content')
<div class="col-sm-8 blog-main">
    @foreach($posts as $post)
        <div class="card" style="margin-bottom: 10px">
            <div class="card-block">
                <h3 class="card-title">{{ $post->Name1 }}</h3>
                <small>Created at: {{ $post->created_at->toFormattedDateString() }}</small>
                <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                <a href="{{$post->id}}" class="btn btn-primary">Details</a>
            </div>
        </div>
    @endforeach

</div>
@endsection

4 Answers 4

4

Firstly you need to install laravel scout

Use: composer require laravel/scout

Next you need to publish the Scout configuration using the vendor:publish command. This command will publish the scout.php to your config directory.

Here is the command: php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

Last step would be Laravel\Scout\Searchable trait to the model you would like to make searchable.

Then its simple for use as: NameOfModel::search($searchText)->get();

Sign up to request clarification or add additional context in comments.

Comments

2

Check this:

$posts = Post::search($searchTerm)->get();

2 Comments

Just to expand on this when you do Post::all() it executes the query immediately so the search query scope doesn't get applied. So apply the scope like in the answer here then you have to call get() to actually execute the query and get the results.
Make sure to add larqavel/scout to your project and add the trait to the model before using search()
1

You are trying to get all record and then applying your scope function, rather then get all records just try:

$searchTerm = $request->input('searchTerm');
$posts = Post::search($searchTerm);
return view('posts.index', compact('posts', 'searchTerm'));

Comments

1

Laravel makes it really easy to do searches, as well as custom searches like live results, and etc. Just make sure to throttle your HTTP requests on the front end.

/**
 * Get a breed by name (returns similar results)
 * @param $term
 * @return \Illuminate\Http\JsonResponse
 */
public function getBreedByName($term)
{
    // Find an Breed by name
    $matchedTerm = Breed::where('text', 'LIKE', '%' . $term . '%')->get();
    return response()->json($matchedTerm);
}

Then create a reference to that controller and method in your routes. In my case, I used the following in /routes/api.php

Route::get('/breeds/search/{term}', 'BreedsController@getBreedByName');

I hope this is helpful! Let me know if you have any questions or if this didn't cover your question.

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.