How to use relationship inside another relationship of other model? - laravel

I want to use public function scheduleTime() to check sechudle_time inside newsLetterSentOn() of News Model.
If this can be done,please help me regarding this.Thank you.
This is News Model
<?php
namespace Modules\Newsletter\Entities;
use Brexis\LaravelWorkflow\Traits\WorkflowTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
/**
* This is for storing news
* Class News
* #package Modules\Newsletter\Entities
*/
class News extends Model {
use WorkflowTrait;
protected $table = 'news_info';
protected $fillable = [
'title', 'header', 'description', 'status', 'created_by', 'media_url', 'media_thumbnail', 'media_type'
];
public function newsLetterSentOn() {
return $this->belongsToMany(Newsletter::class,'news_newsletters','news_id','newsletter_id')
->whereHas('scheduleTime', function($q){
$q->where('schedule_time', '<', date("Y-m-d h:i:s", time()));
});
}
}
This is Newsletter Model
<?php
namespace Modules\Newsletter\Entities;
use Illuminate\Database\Eloquent\Model;
class Newsletter extends Model
{
protected $table = 'newsletters';
protected $hidden = ['pivot'];
protected $fillable = [];
public function scheduleTime()
{
return $this->belongsTo(ScheduleTime::class,'id','newsletter_id');
}
}

You can get nested relationship with dot notation like so:
$news = News::with(['newsLetterSentOn.scheduleTime' => function($q)
$q->where('schedule_time', '<', date("Y-m-d h:i:s", time()));
])->find($id);
Then you can access it through $news like normal.
$news->newsLetterSenton->scheduleTime;

Related

How to use attach with two tables and two connect in laravel?

I use Laravel 8x, and i have two connections:
In .env :
DB_HOST=xx.xx.xx.xx
DB_PORT=xxxx
DB_DATABASE=product
DB_USERNAME=product_sp
DB_PASSWORD=xxxxxxxxx
DB_HOST_PROMOTION=xx.xx.xx.xx
DB_PORT_PROMOTION=xxx
DB_DATABASE_PROMOTION=product_sand
DB_USERNAME_PROMOTION=product_sp
DB_PASSWORD_PROMOTION=xxxxxxxxxxx
In model:
Product.php :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notification;
class Product extends Model
{
use HasFactory;
protected $table = 'product';
protected $keyType = 'string';
public $incrementing = false;
public function discount()
{
return $this->belongsToMany(Discount::class, 'product_discount', 'productId', 'discountId')->withPivot(['id','status', 'quantity', 'createdAt', 'updatedAt', 'createdBy','updatedBy']);
}
}
discount.php :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notification;
class Discount extends Model
{
use HasFactory;
protected $table = 'discount';
protected $connection = 'promotion';
protected $keyType = 'string';
public $incrementing = false;
}
The product_discount table is an intermediate table of discount and product.
In the controller, I use attach
public function store(Request $request)
{
$req = $request->all();
$product = new Product($req);
$extraFieldPivot = [
'id' => (string) Str::uuid(),
'status' => 1,
'quantity' => 1,
'createdAt' => now(),
'updatedAt' => now(),
];
$product->discount()->attach($req['idDiscount'], $extraFieldPivot)
}
But when I check the data. The result has not been saved to the database. So where did I go wrong, please advise me. Thank you very much.
i think your intermediate table needs to be changed like productId to product_id and discountId to discount_id.
and change your relationship according to your change in table
If your model relationship is correct change your store function to
$public function store(Request $request)
{
$req = $request->all();
$product = Product::create($req);
$extraFieldPivot = [
'id' => (string) Str::uuid(),
'status' => 1,
'quantity' => 1,
'createdAt' => now(),
'updatedAt' => now(),
];
$product->discount()->attach($product, $extraFieldPivot)
}

Recursive relationship and nested eager loading with constraints

I'm tryng to create nested eager loading with a where constraint on a recursive relationship
Models and query simulation:
Model Hierarchy
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Hierarchy extends Model
{
protected $table = 'hierarchy';
protected $primaryKey = 'id_hierarchy';
protected $fillable = [
'name',
'parent_id'
];
/**
* #return HasMany
*
* This method implement recursive relationship
*/
public function children()
{
return $this->hasMany(Hierarchy::class, 'parent_id')->with('children');
}
/**
* #return HasMany
*/
public function grandchildren()
{
return $this->hasMany(Grandchild::class, 'id_hierarchy');
}
}
Model Grandchild
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Grandchild extends Model
{
protected $table = 'grandchildren';
protected $primaryKey = 'id';
protected $fillable = [
'id_hierarchy',
'id_something'
'name'
];
/**
* #return BelongsTo
*/
public function hierarchy()
{
return $this->belongsTo(Hierarchy::class, 'id_hierarchy');
}
}
The following query does not return the grandchildren as it was supposed to;
public function read($id)
{
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children.grandchildren' => function ($query) use($id) {
$query->where('id_something', $id);
}])
->get();
}
The problem is in the constrain, because with the following query it returns the grandchildrren (although not filtered because it doesn't have the where condition)
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children.grandchildren'])
->get();
Thanks in advance for suggestions to resolve this issue.
Edited:
As the code is a simulation of the real case, I added 'id_something' to be clearer what is involved.
'id_something' is related to another model that is not represented here
Assuming that HomeCity is one of the related models for GrandChild and the relationship is defined as
//GrandChild.php
public function home_city()
{
return $this->hasMany(HomeCity::class);
}
Then the query to return GrandChild records who live in HomeCity (id_something is a column on home_city table) identified by $id may written as:
public function read($id)
{
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children' => function ($query) use($id) {
$query->with(['grandchildren' => function($query) use($id) {
$query->whereHas('home_city', fn($query) => $query->where('id_something', $id);
}]);
}])
->get();
}

Laravel relationship many to many filtering on pivot field

I have a relationship between Invoice and Shift.
Invoice model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'user_id',
'date_ins',
'closeco',
'closedrh',
'lvl',
'new',
];
public function user()
{
return $this->hasOne(User::class,'id','user_id');
}
/**
* The roles that belong to the invoice.
*/
public function shifts()
{
return $this->belongsToMany(Shift::class, 'invoice_shift')
->withPivot([
'invoice_id', 'shift_id', 'shift_taken_id', 'shift_swapped_date', 'shift_taken_date', 'tas',
'status_tas', 'status_co', 'status_drh', 'back_co',
'msg', 'msg_co', 'msg_drh'
])
->orderBy('status_drh', 'ASC')
->orderBy('status_co', 'ASC');
}
}
Shift model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Shift extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'code',
'description',
];
/**
* The users that belong to the role.
*/
public function invoices()
{
return $this->belongsToMany(Invoice::class, 'invoice_shift')
->orderBy('status_drh', 'ASC')
->orderBy('status_co', 'ASC');
}
}
So I have a pivot table called Invoice_shift.
I cannot extract, starting from invoices table, just invoices that have tas (in invoice_shift table) = current logged user.
I cannot filter as a static value in Invoice model definition with wherepivot because it is dynamic value, every time logged user id is different.
I tried to do this in controller
$invoices = Invoice::with('shifts.invoices')
->orderBy('date_ins', 'DESC')->get();
$filter = $invoices->shifts()
->wherePivot('tas', '=', $user_id)
->get();
but I get an error because I think invoices are a collection ... I tried to insert a foreach...but it doesn't work.
The error message:
Method Illuminate\Database\Eloquent\Collection::shifts does not exist
How can I do this?
Thanks
$invoices is an instance of Illuminate\Database\Eloquent\Collection and therefore relationship shifts() cannot be used..
Maybe you need the correct Eloquent builder to filter invoices using whereHas("relationship", fn)
$filteredInvoices = Invoice::with('shifts.invoices')
->whereHas("shifts", function($query) use ($user_id) {
$query->wherePivot('tas', $user_id)
})
->orderBy('date_ins', 'DESC')
->get();

laravel filter on relationship

hi i have this relationships with these 3 models
Customers
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Customers extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'contr_nom',
'contr_cog',
'benef_nom',
'benef_cog',
'email',
'polizza',
'targa',
'iban',
'int_iban',
'cliente',
];
public function claims()
{
return $this->hasMany(Claims::class);
}
public function refunds()
{
return $this->hasManyThrough(Refunds::class, Claims::class);
}
}
Claims
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Claims extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'dossier',
'date_cla',
];
public function refunds()
{
return $this->hasMany(Refunds::class);
}
public function customers()
{
return $this->belongsTo(Customers::class,'customers_id');
}
}
and Refunds
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Refunds extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'date_ref',
'status_ref',
'disactive',
];
public function services()
{
return $this->belongsToMany(Services::class)
->withPivot(['services_id','services_amount','services_status']);
}
public function claims()
{
return $this->belongsTo(Claims::class,'claims_id');
}
}
i have this in the controller (part of the code)
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))->get();
it works, i can get customers information (parent table) for each dossier ( i put in a datatables)
But i cannot insert another filter based on Refunds table.
I need to show only dossiers where
['status_ref', '>',4]
the problem is that status_ref is in Refunds table
i tried to do somthing like this but no works
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))->refunds()
->where('status_ref', '>',4)
->get();
I cannot understand why....
Thx
You have to use whereHas like:
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))
->whereHas('refunds', function (Builder $query) {
$query->where('status_ref', '>', 4);
})
->get();

Polymorphic - Create inserting record and following up with blank record

I've setup a Polymorphic Relationship on my model for this, I've had to create matching fields to the table that the morph refers to.
So I've created a
Translation Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Translation extends Model
{
protected $table = 'translations';
protected $primaryKey = 'id';
protected $fillable = ['title', 'text_line1', 'text_line2', 'quote', 'language', 'content', 'translationable_type','translationable_id', 'content'];
use SoftDeletes;
public function translationable()
{
return $this->morphTo();
}
}
This is the Polymorph, Then in a seperate model - "Slides"
I've created this:
Slide Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Slide extends Model
{
/**
* Slide table
*/
protected $table = 'slides';
protected $primaryKey = 'id';
public function translations()
{
return $this->morphToMany('App\Models\Translation', 'translationable', 'translations', '', 'translationable_id');
}
}
Then in a controller, I've made a test script...
$slide = Slide::find(16);
$translations = array(
'text_line1' => $slide->text_line1,
'text_line2' => $slide->text_line2,
'language' => 'fr',
'translationable_id' => $slide->id,
'translationable_type' => 'App\Slide'
);
$slide->translations()->create($translations);
When I run this, It creates the record, But also creates another record that is totally blank other than referencing the translationable_id and translationable_type
Anyone know why it would do this?
Cheers.

Resources