issue in laravel relationship search data - laravel

I want to search for usernames from the user's table.
I have used the Laravel relationship(eloquent). I don't search for usernames from users' tables. My code is Below and here I Explain the relationship with All Tablets
I have a query write inside the group controller
public function getGroupsData(Request $request){
$group = Group::with(['memberscount', 'getusername'])->where('groupName', "like", "%" . $request->searchText . "%")
->whereHas('getusername.user', function ($query) use ($request) {
return $query->where('name', 'like', '%'. $request->searchText . '%');
})
->get();
}
memberscount and getusername relationship write-in group model my group model is below
class Group extends Model
{
public function memberscount(){
return $this->hasMany('App\Models\Members', 'group_id', 'id')->where('memberStatus', 'Joined');
}
public function getusername(){
return $this->hasOne('App\Models\Members', 'group_id', 'id')->where('isOwner', 0);
}
}
And user's table relationship in members models. members model is below
class Members extends Model
{
public function user(){
return $this->hasOne('App\User', 'id', 'user_id');
}
/**get group name */
public function group(){
return $this->hasOne('App\Models\Group', 'id', 'group_id');
}
}
I have search user's data this(user) relationship. But I can't search data in a multilevel relationship.

OK, I'm the first step is to rename name relationships in class Group
I think it was more logical names
memberscount -> members
getusername -> owner
And the second step is to search. I write like this:
$group = Group::whereHas('owner', function ($query) use ($request) {
return $query->where('groupName', 'like', '%'. $request->searchText . '%');
})->get();
or more effective and clear code we can save in scope us query like that:
$group = Group::whereHas('owner', function ($query) use ($request) {
return $query->haveGroupName($request->searchText);
})->get();
In the Group model class write code like that:
/**
* Scope a query to only have groupName.
*
* #param \Illuminate\Database\Eloquent\Builder $query
* #param string $param
* #return \Illuminate\Database\Eloquent\Builder
*/
public function scopeHaveGroupName($query, $param)
{
return $query->where('groupName', 'like', '%' . $param . '%');
}

Related

Lazy load Eloquent relation with parameter

I want to lazyload the products with a Laravel Eloquent Entity
/**
* This is in my Orders model
*/
public function product($lang = '') {
switch ($lang){
case '': return $this->belongsTo(ViewProducts::class, 'product_id', 'id');
case 'en_us': return $this->belongsTo(ViewProductsEnUs::class, 'product_id', 'id');
}
}
/**
* This is what works. But its not lazy
*/
$orders = Oders::where('email','me#me.com')
->get();
foreach ($orders as $order){
$product = $order->products('en_us')->first();
}
/**
* This is what I want. Lazyload the product in a different language 'en_us'
*/
$orders = Oders::where('email','me#me.com')
->with('products', // I want to pass the param 'en_us' in any way //)
->get();
Anybody out there who knows how to pass a param (in any way) to the Eloquent Entity so I can lazyload my product data?
I appreciate your help.
Thanks you #TimLewis!
Instead of one relation 'product_' defining multiple relations like
/**
* In my Orders model
*/
public function product_() {
return $this->belongsTo(ViewProducts::class, 'product_id', 'id');
}
public function product_en_us(){
return $this->belongsTo(ViewProductsEnUs::class, 'product_id', 'id');
}
Works!
It's not totally perfect because you have to use it like so:
$productRelation = 'product_' . $lang;
$orders = Oders::where('email','me#me.com')
->with($productRelation)
->get();
// And then get the data like this
$orders->{$productRelation};
But for me it is totally fine!

Or with And Statement in Eloquent livewire

I am using Laravel Livewire dataTables and while searching I am getting an error.
Object of class Illuminate\Database\Eloquent\Builder could not be
converted to string
my method for searching is
public static function search($QUERY)
{
return empty($QUERY) ? static::QUERY()
: static::WHERE(function ($QUERY) {
$QUERY->WHERE('name', 'like', '%' . $QUERY . '%')
->orWhere('email', 'like', '%' . $QUERY . '%');
});
}
Livewire render method
public function render()
{
//$this->roles = ROLE::WHERE('company_id', SESSION('company_id'))->paginate(5);
return VIEW('livewire.users', [
'users' => USER::search($this->search)
->WITH(['role', 'company'])
->WHERE('company_id', SESSION('company_id'))
->orderBy($this->sortField, $this->sortAsc ? 'asc' : 'desc')
->paginate($this->perPage),
]);
}
Instead of having the actual method search(), you can make a scope, which will be rendered the same, but will also have some Laravel-magic helping you.
Replace your search() method on your User model with this scopeSearch() method. You do not change the query where its being used.
/**
* Scope a query to search for users name and email
*
* #param \Illuminate\Database\Eloquent\Builder $query
* #return \Illuminate\Database\Eloquent\Builder
*/
public function scopeSearch(Builder $query, string $search)
{
return $query->where('name', 'like', '%'.$search.'%')
->orWhere('email', 'like', '%'.$search.'%');
}
And import that Builder class, by adding the following line to the top of your User model class,
use Illuminate\Database\Eloquent\Builder;
The trick here is the scope prefix, with a capital S in "search". See the official documentation for more details.

Laravel Eloquent how to override the base query?

I have 2 models shared a same table.
Table name: books, I separate normal book & novel by an attribute called type
Book model
class Book extends \Illuminate\Database\Eloquent\Model
{
protected $table = 'books';
}
Novel model
class Novel extends Book
{
protected $table = 'books';
// Is such a method available?
protected function someMethodToOverride()
{
$this->where('type', 'novel');
}
}
What I want to achieve here is
$results = Novel::where('title', 'LIKE', '%' . $title . '%')->get();
from this query, I want it to pre-set the condition
where('type', 'novel')
Is there any function I can override to achieve this?
use Anonymous Global Scopes and add this boot method in Novel Model
protected static function boot()
{
parent::boot();
static::addGlobalScope('type', function (\Illuminate\Database\Eloquent\Builder $builder) {
$builder->where('type', 'novel');
});
}
now it will automatically add query
$results = Novel::where('title', 'LIKE', '%' . $title . '%')->get();
now If you would like to remove a global scope for a given query, you
may use the withoutGlobalScope method.
Novel::withoutGlobalScope('type')->get();
for more information read this article
In Model You can use scope:
public function scopeOfType($query, $type)
{
return $query->where('type', $type);
}
And pass the parameters when calling the scope:
Model::ofType('novel')
->where('title', 'LIKE', '%' . $title . '%')
->get();
refer link Laravel Scope

Laravel : Search Query Within Relationship

When I am adding a new post in my app there is a 7 tables to affect when I add single post. To fetch all posts with all post data my simple query look like:
$userPost = Post::with(['product','postattribute.attribute.category','user.userDetails'])
->offset($offset)
->limit($limit)
->whereStatus("Active")
->whereIn('product_id', $userApprovalProductIDs)
->orderBy('id','desc')
->get();
So it is retrun all data which I want. Now I want to implement search query within all tables, currently I am able to search only posts table.
If I am doing search on category table with categoryTitle I am trying to code like
where('category.title','=', $serachTitle)
But it is not working in my case.
POST model relationship :
public function user() {
return $this->belongsTo(User::class);
}
public function product() {
return $this->belongsTo(Product::class);
}
public function postattribute() {
return $this->hasMany(PostAttribute::class);
}
POSTATTRIBUTES model relationship :
public function post() {
return $this->belongsTo(Post::class);
}
public function attribute() {
return $this->belongsTo(Attribute::class);
}
ATTRIBUTES model relationship :
public function category() {
return $this->belongsTo(Category::class);
}
public function attributes() {
return $this->belongsTo(Attribute::class);
}
How can I do this ?
To apply filter on your nested relations you could use whereHas
$userPost = Post::with(['product','postattribute.attribute.category','user.userDetails'])
->offset($offset)
->limit($limit)
->whereStatus("Active")
->whereIn('product_id', $userApprovalProductIDs)
->whereHas('postattribute.attribute.category', function ($query) use($serachTitle) {
$query->where('title', '=', $searchTitle);
})
->orderBy('id','desc')
->get();
Querying Relationship Existence
From comments what i understood is you want to know how to search within each relation for a post , I already added an example to search with category title
->whereHas('postattribute.attribute', function ($query) use($var) {
$query->where('some_field_of_attribute_table', '=', $var);
})
->whereHas('postattribute', function ($query) use($var) {
$query->where('some_field_of_postattribute_table', '=', $var);
})

How can I use whereHas in the morphTo relation laravel?

My product model like this :
<?php
...
class Product extends Model
{
...
protected $fillable = ['name','photo','description',...];
public function favorites(){
return $this->morphMany(Favorite::class, 'favoritable');
}
}
My favorite model like this :
<?php
...
class Favorite extends Model
{
...
protected $fillable = ['user_id', 'favoritable_id', 'favoritable_type'];
public function favoritable()
{
return $this->morphTo();
}
}
My laravel eloquent like this :
$q = $param['q'];
$query = Favorite->where('user_id', auth()->user()->id)
->with('favoritable');
if($q) {
$query->whereHas('favoritable', function ($query) use ($q) {
$query->where('name', 'like', "%$q%");
});
}
$query = $query->paginate(5);
return $query
If the script executed, there exist error like this :
Unknown column 'name'
How can I solve this problem?
Laravel 5.8 include new features for querying polymorphic relations.
The whereHasMorph() make it possible to query polymorphic relationships with something like the following:
Comment::whereHasMorph('commentable', [Post::class, Video::class], function($query){
$query->where('title', 'foo');
})->get();
Which produces following query:
select * from "comments"
where (
(
"commentable_type" = 'App\Post' and exists (
select * from "posts"
where "comments"."commentable_id" = "posts"."id" and "title" = 'foo'
)
) or (
"commentable_type" = 'App\Video' and exists (
select * from "videos"
where "comments"."commentable_id" = "videos"."id" and "title" = 'foo'
)
)
)
Solved
I add this method :
public function product()
{
return $this->belongsTo(Product::class, 'favoritable_id')
->where('favorites.favoritable_type', Product::class);
}
in favorite model
And I change the laravel eloquent to be like this :
$query->whereHas('product', function ($query) use ($q) {
$query->where('name', 'like', "%$q%");
});
It works

Resources