Reputation: 420
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
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
Reputation: 113
Change your location model relationship
public function landmarks(){
return $this->hasMany('App\Landmark');
}
Upvotes: 0
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
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