Populate laravel object with relationships - laravel

I want to populate Every CustomerEvent with the Customer related to the CustomerEvent.
When I Loop through the object and call to $customerevent->customer foreach object I can get the customer related to that event but Can I populate the all objects in the main object without looping through every single event ?
I want to do something like this:
$typeOne = CustomerEvent::typeOne()->get();
$customersWithTypeOne = $typeOne->Customers;
Here my code:
Table 1: "events"
id, customer_id
Model for Table 1 "CustomerEvent":
<?php
class CustomerEvent extends Eloquent{
protected $guarded = ['id'];
public $table = "event";
protected $softDelete = true;
public function scopeTypeOne($query)
{
$followUps = $query->where('type_id', '=', '1');
}
public function Customers()
{
return $this->belongsTo('Customer', 'customer_id');
}
}
Table 2: "customers"
id
Model for Table 2 "Customers":
<?php class Customer extends BaseModel{
protected $guarded = ['id'];
}
EventController:
public function index()
{
$typeOne = CustomerEvent::typeOne()->get();
$customersWithTypeOne = $typeOne->Customers;
dd($customersWithTypeOne);
}

From you database scheme I see customer has many events, so I would recommend to define this relationship in you Customer model.
class Customer extends BaseModel{
protected $guarded = ['id'];
public function events()
{
return $this->hasMany('CustomerEvent', 'customer_id');
}
}
Then you will be able to query customers with events:
$customersWithTypeOne = Customer::whereHas('events', function($query){
$query->where('type_id', 1);
})->get()

Maybe Ardent can help you: https://github.com/laravelbook/ardent
It's an extension for Eloquent models and very popular.

Related

Laravel filtering query results with relations

I have this relations
and defined models for all 3 tables
class Employee extends Model
{
use HasFactory;
protected $table = 'employees';
public function departments()
{
return $this->belongsToMany(Department::class, 'dept_emp', 'emp_no', 'dept_no', 'emp_no', 'dept_no');
}
}
class Department extends Model
{
use HasFactory;
protected $table = 'departments';
}
class Dept_emp extends Model
{
use HasFactory;
protected $table = 'dept_emp';
}
And in my controller
$employees = Employee::with('departments')->paginate(50);
I want to filter this query result to be able to select only one chosen department and not all of them.
I tried adding to employee model this function
public function scopeDepartment($query, $department)
{
return $query->where('dept_no',$department);
}
but it isn't working. Can someone advice me how to filter query results with relations?
you can query within with relation as like
$employees = Employee::with(['departments' => function($q) use ($dept_id){
$q->where('dept_no',$dept_id);
}])->paginate(50);
$dept_id is the id of department i.e $dept_id = $request->department_id something like

Laravel Eloquent relationship data retrieve

I have below code to get data from database,
$profile = Profiles::find(1);
$currency = Profiles::find($profile->currency_id)->currency;
Then created a relationship in the model as below,
class Profiles extends Model
{
use HasFactory;
protected $table = 'Profiles';
protected $primaryKey = 'profile_id';
public function Currency()
{
return $this->belongsTo(Currencies::class, 'currency_id');
}
}
class Currencies extends Model
{
use HasFactory;
protected $table = 'Currencies';
protected $primaryKey = 'currency_id';
public function profile()
{
return $this->hasOne(Profiles::class, 'currency_id');
}
}
Problem is that there is only 1 profile and 100 currency, currency_id is a foreign key in Profiles table,
I could not get data and get this error, Trying to get property 'currency' of non-object"
If i use $currency = Profiles::find(1)->currency; then it retrieve first row of Curriencies table which is not required data.
How can I get currency row for that specific profile?
The problem is that the find() method will look for the primaryKey and in your second call the currency_id is not the pk.
Two solution for you:
replace the find by a where clause like so: $currency = Profiles::where('currency_id',$profile->currency_id)->value('currency')
Or a more Laravel way to do it, through the relationship $currency = $profile->currency;

passing datas with relationship in the view laravel

if i have this models relationship
Claims : this table hasMany(Refunds)
Refunds: with data of various request. this table belongsTo(Claims) AND belongsToMany(Services)
Services: with list of services. this table belongsToMany(Refunds)
Refunds-Services: bridge table for refunds and services
Claims model
class Claims extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'dossier',
'date_cla',
];
public function refunds()
{
return $this->hasMany(Refunds::class);
}
}
Refunds model
class Refunds extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'date_ref',
'status_ref',
];
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');
}
}
Services model
class Services extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'code',
'name',
];
public function refunds()
{
return $this->belongsToMany(Refunds::class);
}
}
and in my controller this method
if ($request->ajax()) {
$dossier = request('dossier');
$claim = Claims::with('refunds')
->where('dossier', '=', $dossier)->first();
$
$view = view('pages.modify', compact('claim'));
$sections = $view->renderSections()['table'];
return $sections;
}
how can insert in the Controller the relationship between Refunds and Service to use the pivot (service_amount is in the Refunds-Services table)
<li>- {{ $item->pivot->services_amount }}</li>
Because now in the view cannot see this relationship
Thx
You can use Nested Eager Loading
$claim = Claims::with('refunds.services')
->where('dossier', '=', $dossier)->first();
As per the documentation:
To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:
$books = App\Book::with('author.contacts')->get();

Laravel | oneToMany with two foreign keys

I have two tables, invoice_header and invoice_detail
Both tables have loc_id and invo_no as reference keys between them.
How can I link them inside the model, can I use array for foreign keys?
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class InvoiceDetail extends Model
{
protected $table = 'invoice_detail';
public $timestamps = false;
protected $fillable = ['invo_no','loc_id','serial','item_id','qty','rtp','cost',
'discount','type'];
public function item(){
return $this->belongsTo('App\InvoiceHeader', ['loc_id', 'invo_no']);
}
}
https://laravel.com/docs/5.5/eloquent-relationships#one-to-many
You will want a details model and and invoice header model and invoice model and inter connect them.follow the article or rename your model to invoice and make to functions
//details
public function invoice(){
return $this->belongsTo(Invoice::class);
}
//invoice model
public function details(){
return $this->hasMany(InvoiceDetails::class);
}
public function headers(){
return $this->hasMany(InvoiceHeaders::class);
}
//headers model
public function invoice(){
return $this->belongsTo(Invoice::class);
}
//then you can get details and headers through
$invoice = Invoice::find(1);
$details = $invoice->details;
$headers = $invoice->headers;

Laravel Eloquent for display row from subject table?

i have three database tables
category (id,name)
subcategory (id,name,category_id) foreign_key category_id on table category(id).
subject(id,name,subcategory_id) foreign_key subcategory_id on table subcategory (id).
i want a row containing the following -
subject_id subject_name category_name subcategory_id
how to do this using eloquent .and if approach is wrong .please suggest a good method to achieve the same .
Assuming you have the following models:
// Category Model
class Category extends \Eloquent {
protected $table = "category";
public function subcategory(){
$this->hasMany('Subcategory','category_id');
}
}
// Subcategory Model
class Subcategory extends \Eloquent {
protected $table = "subcategory";
public function category(){
$this->belongsTo('Category', 'category_id');
}
pubic function subject(){
$this->hasMany('Subject', 'subcategory_id');
}
}
// Subject model
class Subject extends \Eloquent {
protected $table = "subject";
public function subcategory(){
$this->belongsTo('Subcategory','subcategory_id');
}
}
You can get the data in your controller as follows:
// for subject with id 1
public function getOneRow(){
$subject = Subject::with('subcategory.category')->findOrFail(1);
//subject_id = $subject->id
//subject_name = $subject->name
//subcategory_id = $subject->subcategory->id
//category_name = $subject->subcategory->category->name
return array("subject_name"=>$subject->name, "category_name"=>$subject->subcategory->id, "subcategory_name"=>$subject->subcategory->category->name);
}
// for all subjects
public function getOneRow(){
$subjects = Subject::with('subcategory.category')->all();
$out = array();
foreach($subjects as $subject){
// each row
//subject_id = $subject->id
//subject_name = $subject->name
//subcategory_id = $subject->subcategory->id
//category_name = $subject->subcategory->category->name
$out[] = array("subject_name"=>$subject->name, "category_name"=>$subject->subcategory->id, "subcategory_name"=>$subject->subcategory->category->name);
}
return $out;
}
Edit for Laravel 5.1
Your models will be defined differently. Here's an example. Or follow the docs:
// Category Model Laravel 5.1
use Illuminate\Database\Eloquent\Model;
class Category extends Model {
protected $table = "category";
public function subcategory(){
$this->hasMany('Subcategory','category_id');
}
}
Edit: Completed the functions with return statements as requested in comment

Resources