I Love Code
I Love Code

Reputation: 420

Laravel Undefined variable: locations error with search function

I have a Undefined variable: locations error with building a simple search function. It is my first time building a search function and I am really struggling with it so far.

I have 2 tables: Locations and Landmarks. One location can have many landmarks. A landmark can only have one location.

I am trying to search a Location and want the landmarks stored in the database with location_id to view when I search.

Here is my Location model relationship:

public function landmarks(){
  return $this->hasMany('App\Landmarks');
}

Here is the landmark relationship to the location:

  public function location(){
    return $this->belongsTo('App\Location');
  }

My SearchController:

  public function search(Request $request){
      $landmarks = $request->input('location');

      //now get all user and services in one go without looping using eager loading
      //In your foreach() loop, if you have 1000 users you will make 1000 queries

      $locations = Locations::with('landmarks', function($query) use ($landmarks) {
           $query->where('landmarks', 'LIKE', '%' . $landmarks . '%');
      })->get();

      return view('pages.browse', compact('locations'));
  }

Route:

Route::get('/browse', 'SearchController@search');

View:

<form action="" class="search-form" method="GET">
    <input type="text" name="location" placeholder="Search" required>
    <button class="search-btn" type="submit"><i class="flaticon-026-search"></i></button>
 </form>

  @foreach($landmarks as $landmark)
    <p>{{$landmark->name}}</p>
  @endforeach

Upvotes: 1

Views: 759

Answers (4)

plmrlnsnts
plmrlnsnts

Reputation: 1684

Since it's clear that your search() method is never being called, we moved the contents of your function inside your index() method.

public function index(Request $request) { 

    $landmarks = $request->input('location'); 

    $locations = Locations::with(['landmarks', function($query) use ($landmarks) { 
        $query->where('landmarks', 'LIKE', '%' . $landmarks . '%'); 
    }])->get(); 

    return view('pages.search', compact('locations')); 

}

But then you received another error:

mb_strpos() expects parameter 1 to be string, object given

Because your with() function is incorrect, the proper way to do this is:

with(['landmarks' => function ($query) use($landmarks) {
    $query->where('landmarks', 'LIKE', '%' . $landmarks . '%'); 
}])

Also, I think you are trying to get all locations that have a landmark matching a given keyword. So instead of with(), which eager loads the relationship, you might as well change it to whereHas() that will filter the results if a relationship exists in a model.

Your code would now look like this:

$locations = Locations::whereHas('landmarks', function($query) use ($landmarks) { 
    $query->where('landmarks', 'LIKE', '%' . $landmarks . '%'); 
})->get(); 

Upvotes: 1

Pedro
Pedro

Reputation: 113

Change your location model relationship

public function landmarks(){
    return $this->hasMany('App\Landmark');
}

Upvotes: 0

sumit
sumit

Reputation: 15464

You need to loop over eager loaded content , try below if you have single location and multiple landmark

  @foreach($locations->landmarks as $landmark)
    <p>{{$landmark->name}}</p>
  @endforeach

if you have mutiple location and mutiple landmark inside it try below

@foreach($locations as $location)
        @foreach($location->landmarks as $landmark)
           <p>{{$landmark->name}}</p>
        @endforeach
  @endforeach

Upvotes: 1

parker_codes
parker_codes

Reputation: 3397

Are you sure the error isn't that you're missing $landmarks? You are passing locations to your view, but then looping through landmarks.

Upvotes: 0

Related Questions