Eloquent collections with a relation of another relation - laravel

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');

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);

How can i use related model scope inside whereHas Laravel 8

I have two models. Task and TaskCheck
in TaskCheck i have
class TaskCheck extends Model
{
public function task(): BelongsTo
{
return $this->belongsTo(Task::class);
}
public function owner(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function scopeOwnedBy(Builder $query, int $userId): Builder
{
return $query->where('user_id', '=', $userId);
}
}
in Task model i have
class Task extends Model
{
public function taskCheck(): HasMany
{
return $this->hasMany(TaskCheck::class)->with(['taskState', 'owner']);
}
}
And would like to use something like this:
public function scopeHasOwner(Builder $query, int $taskOwnerId): Builder
{
return $query->whereHas('taskCheck', function ($q) use ($taskOwnerId) {
$q->hasOwner($taskOwnerId);
});
}
however this throws exception Call to undefined method App\Models\Task::hasOwner() as it seems inner query is not aware of Task model.
I know I could use this instead and it works
public function scopeHasOwner(Builder $query, int $taskOwnerId): Builder
{
return $query->whereHas('taskCheck', function ($q) use ($taskOwnerId) {
$q->where('user_id', '=', $taskOwnerId);
});
}
but i would rather not repeat the where clause in every related model, because there are more related models deeper in relationships which would use similar functionality and i would like to have it on one place only.
In your TaskCheck model, you have ownedBy() scope, but you called hasOwner() in the whereHas query.
Change your query to ownedBy()
$query->whereHas('taskCheck', function ($q) use ($taskOwnerId) {
$q->ownedBY($taskOwnerId);
});

Laravel check hasMany of hasMany relationship if has IDs?

Hello I have the following relationship setup:
Product class:
public function attributes()
{
return $this->hasMany(ProductAttribute::class);
}
ProductAttribute class:
public function attribute()
{
return $this->belongsTo(Attribute::class);
}
public function values()
{
return $this->hasMany(ProductAttributeValue::class, 'product_attribute_id');
}
ProductAttributeValue class:
public function attributeValue()
{
return $this->belongsTo(AttributeValue::class, 'attribute_value_id');
}
How to check if Product has values with ids 5 and 15?
I am trying to make a query like this:
Product::whereHas('values', function($q) use ($product_values_ids) {
$q->whereIn('attribute_value_id', $product_values_ids);
})->get();
however it is not working. I cannot access directly $product->values.
Any suggestions on how to access directly the values of attributes from the Product?
Update:
I have just managed to make it work with a many to many trough relationship:
Product class:
public function values()
{
return $this->hasManyThrough(ProductAttributeValue::class, ProductAttribute::class);
}
is there a way to get only the results that have all the ids listed in the $product_values_ids array?
You have to add new relation to Product model:
public function values(): HasManyThrough
{
return $this->hasManyThrough(ProductAttributeValue::class, ProductAttribute::class);
}
and then:
$builder = Product::query();
foreach($product_values_ids as $id) {
$builder->whereHas('values', function($q) use ($id) {
$q->where('id', $id);
});
}
$product = $builder->get();

Sort eloquent model with relationships Laravel

I have a model that I want to sort based on a relationship property.
First model "DeviceType":
public function make()
{
return $this->hasMany(DeviceMake::class);
}
Second model: "DeviceMake":
public function type()
{
return $this->hasOne(DeviceType::class, 'id', 'device_type_id');
}
public function model()
{
return $this->hasMany(DeviceModel::class);
}
Controller:
$type = DeviceType::with(['make'])->where('id', '=', $device_type_id)->first();
Table name is device_makes and I want to sort it by name. How can I do this?
And what about?
$type = DeviceType::with(['make' => function ($query) {
$query->orderBy('name', 'asc');
}])->where('id', '=', $device_type_id)->first();
Please note that first() will only return the first model that matches your query whereas get() will return all of them.
Maybe you could try this instead in your Model:
public function make() {
return $this->hasMany(DeviceMake::class)->orderBy('name', 'asc');
}

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()

Resources