Undefined variable but it's already declared Laravel - laravel

I'm having some problems with my website.
Lately, I've been working on a "filtering page" where the user selects/writes a character, and then it searches X data with that character (From A-Z and 0-9). The character can be optional.
This is my getAffiliates function:
public static function getAffiliates($community_id, $character) {
if (!empty($character)) {
$character = strval($character);
if (is_numeric($character)) {
$users = UserCommunity::with('user')->where('community_id', $community_id)->whereHas('user', function($q) {
$q->where('name', 'regexp', '^[0-9]+');
})->get();
} else {
$users = UserCommunity::with('user')->where('community_id', $community_id)->whereHas('user', function($q) {
$q->where('name', 'like', $character.'%');
})->get();
}
} else {
$users = UserCommunity::with('user')->where('community_id', $community_id)->take(50)->get();
}
return $users;
}
What this code does is, given an X $community_id, and an X $character, it will determine whether $character is integer or not. Then, it will do a query to the database and it will retrieve a collection conditioned on the given parameters. Basically, the query looks for a value where the initial character equals my $character parameter.
What I don't know is, why am I getting the "undefined variable $character" error?
My controller's code is this (Notice the parameter can be null):
Can someone explain what is actually wrong?
UPDATE With the Full Trace Error

You have to use variable top of where has function. to access it.
public static function getAffiliates($community_id, $character) {
if (!empty($character)) {
$character = strval($character);
if (is_numeric($character)) {
$users = UserCommunity::with('user')->where('community_id', $community_id)->whereHas('user', function($q) {
$q->where('name', 'regexp', '^[0-9]+');
})->get();
} else {
$users = UserCommunity::with('user')->where('community_id', $community_id)->whereHas('user', function($q) use ($character) {
$q->where('name', 'like', $character.'%');
})->get();
}
} else {
$users = UserCommunity::with('user')->where('community_id', $community_id)->take(50)->get();
}
return $users;
}

Your $character variable is defined outside the scope of where it's being used.
You can use the use keyword to bring the variable into the closure's scope like this:
$users = UserCommunity::with('user')->where('community_id', $community_id)
->whereHas('user', function($q) use($character) { // <-- do this
$q->where('name', 'like', $character.'%');
})->get();

Related

Laravel query not getting correct results

When a user types keywords for the search filter, I want to query tags related to posts. If the keyword is "water body" the result of the filter should return posts that have both tags (water and body). My code below shows results that has either of the tags
How do I query to get only collections that contain both tags?
public function searchFilter(Request $request, Post $post){
$terms = explode(" ", $request->input('keyword'));
$posts = $post->newQuery();
$page = (int)$request->input('page', 1);
$perPage = (int)$request->input('perPage', 10);
$keyword = $request->keyword;
if($request->has('keyword')){
$posts->where(function($query) use($keyword) {
$query->Where('name','LIKE', '%'.$keyword.'%')
->orWhereHas('super', function($q) use ($keyword)
{
$q->where('name','LIKE', '%'.$keyword.'%');
})
->orWhereHas('tags', function($q) use ($keyword)
{
$q->where('name','LIKE', '%'.$keyword.'%');
});
});
}
}
You can explode your keywords and then add orWhereHas for each keyword:
//...
$keywords = explode(' ', $request->keyword);
//...
// Then in your query, use foreach to search for each keyword (do the same for each field
foreach ($keywords as $keyword) {
$query->orWhereHas('tags', function($q) use ($keyword) {
$q->where('name','LIKE', '%'.$keyword.'%');
});
}
````

How to search from relationship data ? In laravel

public function scopeSearch($query, $value)
{
$searchValues = explode(' ', $value);
if (!$value) return $query;
return $query->where(function ($q) use ($searchValues) {
foreach ($searchValues as $token) {
$q->orWhere('name', 'like', "%{$token}%");
$q->orWhere('street', 'like', "%{$token}%");
}
});
}
I want to search the data. This model also has
public function brands()
{
return $this->belongsToMany(Brand::class, 'dealer_brands');
}
public function province()
{
return $this->belongsTo(Province::class);
}
How can I get data from the relastionship. Like Dealer(model) has data Nmae = josh , brand_id = 1 {brand.name = samsung} , province_id = 2 (province.name = "aligora"). When I search Josh Samsung Alogora, I want to ge the data. When I only search aligora, I want to get the data of model having province aligora. hOW CAN I MODIFY CODE?
looking at your model relationships. This may work for you
public function scopeSearch($query, $value)
{
if (!$value) return $query;
$searchValues = explode(' ', $value);
return $query->where(function ($q) use ($searchValues) {
foreach ($searchValues as $token) {
$q->where('name', 'like', "%{$token}%")
->orWhere('street', 'like', "%{$token}%")
->orWhereHas('brands', function ($sub_q) use ($searchValues) {
$sub_q->where('name', 'like', "%{$token}%")
->orWhere('street', 'like', "%{$token}%");
})
->orWhereHas('province', function ($sub_q) use ($searchValues) {
$sub_q->where('name', 'like', "%{$token}%")
->orWhere('street', 'like', "%{$token}%");
});
}
});
}
I have no idea about column names in related tables so repeating name and street. you can change as per requirement

Laravel eloquent search functionality

I'm currently creating a search functionality on my index blade file.
I have different users that have different stores per area.
my User model:
function area() {
return $this->hasOne('App\Area');
}
function role() {
return $this->belongsTo('App\Role');
}
function reports() {
return $this->hasMany('App\Report');
}
function stores() {
return $this->hasManyThrough('App\Store', 'App\Area');
}
}
Area model:
function reports() {
return $this->hasMany('App\Report');
}
function stores() {
return $this->hasMany('App\Store');
}
function user() {
return $this->belongsTo('App\User');
}
Store model:
function district() {
return $this->belongsTo('App\District');
}
function cluster() {
return $this->belongsTo('App\Cluster');
}
function city() {
return $this->belongsTo('App\City');
}
function area() {
return $this->belongsTo('App\Area');
}
I have managed to make the functionality work on admin account (where in you can see all stores) by:
function index(Request $request) {
if($request->has('search')) {
$stores = Store::whereHas('city', function($query) use($request) {
$query->where('name', 'like', '%' . $request->search . '%');
})->orWhereHas('cluster', function($query) use($request) {
$query->where('name', 'like', '%' .$request->search. '%');
})->orWhere('name', 'like', '%' .$request->search. '%')
->orWhere('store_no', 'like', '%' .$request->search. '%')->paginate(10);
} else {
$stores = Store::orderBy('created_at', 'desc')->paginate(10);
}
return view('/stores.store_list', compact('stores'));
what I want to do on user accounts is:
function index(Request $request) {
if($request->has('search')) {
$id = Auth::user()->id;
$query = $request->search;
$user = User::find($id)->stores()->where('name', 'like', '%' . $query . '%')->paginate(10);
} else {
$id = Auth::user()->id;
$user = User::find($id)->stores()->orderBy('created_at', 'desc')->paginate(10);
}
return view('/stores.store_list', compact('user'));
}
I'm having an error when searching:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'name' in where clause is ambiguous (SQL: select count(*) as aggregate from stores inner join areas on areas.id = stores.area_id where areas.user_id = 6 and name like %houston% and stores.deleted_at is null)
can anyone point me on the right direction and let me know what i'm missing here? Thank you!
When you have error such is
Column 'some_column_name_here' in where clause is ambiguous...
it means that there is complex query associated with more tables of which at least two those have same table name in their structure and that table name is used in complex query (in some ON, WHERE...) in this case WHERE as error states.
You always can use table_name.column_name {table name dot column name} syntax to point syntax at exact table meant (ambiguous).

I can't use variable in a function whereHas

I'm new with laravel. I can't use $class _id in a function whereHas. What should I do?
public function show($classroom_id)
{
$classrooms = Group::whereHas('members', function ($query) {
$query->where([['user_id', '=', Auth::id()], ['classroom_id', $classroom_id]]);
})->get();
return response()->json($classrooms);
}
See use (classroom_id)
$groups = Group::whereHas('natures', function($q) use($classroom_id)
{
$q->where('classroom_id', '=', $classroom_id);
});

Laravel - passing array of columns in 'where' clause

I have a search query like this:
$data = User::where('first_name', 'like', '%'.$query.'%')
->orWhere('last_name', 'like', '%'.$query.'%')
->get();
Now, I have many models, each with different column names. Instead of defining a search() function into every controller, I want to do this:
// User
public static function searchableFields()
{
return ['first_name', 'last_name'];
}
// Some other model
public static function searchableFields()
{
return ['name', 'description'];
}
And put the search logic in a shared controller, something like this:
$data = $classname::
where($classname::searchableFields(), 'like', '%'.$query.'%')
->get();
How can I achieve this?
Thanks a lot.
You can loop over the fields and add them to your Eloquent query one by one.
$data = $classname::where(function ($query) use ($classname) {
foreach ($classname::searchableFields() as $field)
$query->orWhere($field, 'like', '%' . $query . '%');
})->get();
I would use scope for that.
You can create base model that all the models should extend (and this model should extend Eloquent model) and in this model you should add such method:
public function scopeMatchingSearch($query, $string)
{
$query->where(function($q) use ($string) {
foreach (static::searchableFields() as $field) {
$q->orWhere($field, 'LIKE', '%'.$string.'%');
}
});
}
Now you can make a search like this:
$data = User::matchingSearch($query)->get();
Just to avoid confusion - $query parameter passed to matchingSearch becomes $string parameter in this method.
You can try something like this.
// Controller
function getIndex(Request $request)
{
$this->data['users'] = User::orderBy('first_name','asc')->get();
if ($request->has('keyword')) {
$results = User::search($request->keyword);
$this->data['users'] = collect([$results])->collapse()->sortBy('first_name');
}
}
// Model
function search($keyword)
{
$results = [];
$search_list = ['first_name','last_name'];
foreach ($search_list as $value)
{
$search_data = User::where($value,'LIKE','%'.$keyword.'%')->get();
foreach ($search_data as $search_value) {
$exist = 0;
if (count($results)) {
foreach ($results as $v) {
if ($search_value->id == $v->id) {
$exist++;
}
}
if ($exist == 0) {
$results[] = $search_value;
}
} else{
$results[] = $search_value;
}
}
}
return $results;
}

Resources