How to restrict whereHas to ONLY match where condition? - laravel

I am using Laravel 6.0 and PostgreSQL on Homestead.
This query is returning services which has at least one post with is_assistant = true:
Service::with('posts')
->whereHas('posts', function ($q) {
$q->where('is_assistant', true);
})
->get();
Models:
class Service extends Model
{
public function posts()
{
return $this->belongsToMany('App\Post');
}
}
class Post extends Model
{
protected $casts = [
'is_assistant' => 'boolean',
];
}
How to write an Eloquent query that get services which has ONLY posts with is_assistant = true?

Can use the whereDoesntHave method:
Service::with('posts')
->whereDoesntHave('posts', function ($q) {
$q->where('is_assistant', false);
})
->get();

Related

Laravel Single User Data In A Multichained Distant Relationship

I have three models as per the code below.I have a problem of returning a single savings data for authenticated users. Any help will be highly appreciated.
I want a low like this:
$savings =Savings::client()->client_users()->where('user_id', '=', Auth::user()->id)->get();
Savings Model
class Savings extends Model
{
public function client()
{
return $this->hasOne(Client::class, 'id', 'client_id');
}
}
Client Model
class Client extends Model
{
public function client_users()
{
return $this->hasMany(ClientUser::class, 'client_id', 'id');
}
}
Client User Model
class ClientUser extends Model
{
public function user()
{
return $this->hasOne(User::class, 'id', 'user_id');
}
}
You can try this query:
$user = Auth::user();
return Savings::whereHas('client.client_users', function ($query) use ($user){
$query->where('user_id', $user->id);
}])->get();
I have fixed the above error. Thanks #Maik Lowrey
$user = Auth::user();
$savings= Savings::whereHas('client.client_users', function ($query) use ($user){
$query->where('user_id', $user->id);
})->get();
return response()->json($savings);
//return response($savings);

Eloquent collections with a relation of another relation

I have Post eloquent related with PostCategory and my collection is good.
class Post extends Model
{
public function post_categories()
{
return $this->belongsTo(PostCategory::class, 'category_id');
}
public function detail($slug_category, $slug)
{
$detail = Post::with('post_categories')
->whereHas('post_categories', function ($query) use ($slug_category){
$query->where('category_slug', $slug_category);
})->where('slug', $slug)
->first();
return($detail);
}
}
I have this another class 'Players' where i need to have a collection with all user's posts with PostCategory category relation.
class Players extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
public function detail($slug_category, $slug_name)
{
$detail = Player::with('posts')
->whereHas('players_info', function ($query) use ($slug_name){
$query->where('slug', $slug_name);
})
->whereHas('player_categories', function ($query) use ($slug_category){
$query->where('category_slug', $slug_category);
})->first();
return($detail);
}
}
I read something about "belongsToMany" and "withPivot", but I'm still confused for correct way.
What can I do to resolve this?
thanks!
I solved just with this.
return $this->hasMany(Post::class)->with('post_categories');

Getting filtered data from many to many relationship

I need to get filtered data from many to many relationship from Post and Tag tables.
I have Post Model:
class Post extends Model
{
public function tag()
{
return $this->belongsToMany('App\Tag', 'post_tag','post_id','tag_id');
}
}
And Tag Model like:
Class Tag extends Model
{
protected $fillable = ['name'];
public function post()
{
return $this->belongsToMany(Post::class, 'post_tag');
}
}
But when I try to get filtered data based on tag_id:
if($request->filled('tag_id')){
$posts = Post::whereHas(
['tag' => function($query) use($request)
{
$query->where('tag_id','=', $request->input('tag_id'));
}
])->get();
}
It doesnt work
according to laravel doc
whereHas take string and callback function as parameters not an array:
$posts = Post::whereHas(
'tag' ,function($query) use($request)
{
$query->where('tag_id','=', $request->input('tag_id'));
}
)->get();

how to use laravel Scope in a relationship?

I'm using laravel
I have two models
Product
class Product extends Model
{
public function productcategories(){
return $this->hasOne('App\Product\Productcategorie','CategoryID','ProductCategoryId');
}
}
and Productcategorie
class Productcategorie extends Model
{
protected $primaryKey = 'CategoryID';
public function product(){
return $this->belongsToMany('App\Product\Product','ProductCategoryId','CategoryID');
}
public function scopeCp($query,$id){
return $query->where('categoryparent_id', '=', $id);
}
}
The Product model has a scope Cpscope
and i have ProductController with function
function productCatgoryPaFilter(Request $request){
$categories= Categoryparent::with('categories')->get();
$id=$request->id;
return $product = Product::with('productcategories')->with('productoption.option')->orderBy('created_at','DESC')->get();
}
i want to get all products with categoryparent_id equal to passed parametre in scope
how can i do it?
If you want to filter data in relational model, use whereHas(). Though i have not tested, give it a try
Product::whereHas('productcategories', function ($query) use($id) {
$query->cp($id);
})
->orderBy('created_at','DESC')->get()

Create filter in laravel API controller

Hi i want to create a filter to show mosque with event or activities only. Any idea to display the mosque with activities or events only ?. This one from back-end that later will be fetch using react
namespace App\Http\Controllers;
use App\Event;
use App\Mosque;
use App\Activity;
use Illuminate\Http\Request;
class NotificationController extends Controller
{
public function list()
{
$mosques = Mosque::get();
$array = array();
foreach ($mosques as $mosque) {
array_push($array, [
'mosque_name' => $mosque->name,
'mosque_image'=> $mosque->image
]);
}
return $array;
return response()->json(['result' => $mosques]);
}
public function show(Request $request)
{
$mosque = Mosque::find($request->mosque_id);
$mosque->activities;
$mosque->events;
return response()->json(['result' => $mosque]);
}
}
To filter rows from database, which has particular relationship, you can use whereHas() function on QueryBuilder Instance.
$mosques = Mosque::whereHas('events')
->orWhereHas('activities')
->get();
This function will only returns mosques which has activities or events, other mosques will not fetch.
Also if you only need the name and the image you can filter them too
$mosques = Mosque::whereHas('events')
->orWhereHas('activities')
->get(['name','image']);
You can try this
public function show(Request $request)
{
$mosque = Mosque::find($request->mosque_id);
$mosque->activities;
$mosque->events;
return response()->json(['result' => $mosque->events ]);
}

Resources