SlideShare a Scribd company logo
1 of 22
Hacking Laravel
Custom relationships with Eloquent
Alex Weissman
https://chat.userfrosting.com
@userfrosting
Basic Relationships
student subject
Alice Freestyling
Alice Beatboxing
David Beatboxing
David Turntabling
name team
Alice London
David Liverpool
Abdullah London
person partner
Alice David
Abdullah Louis
Model::hasOne
Model::hasMany
Model::belongsToMany
Ternary Relationships
Job
Worker
Locationm:m:m
Ternary Relationships
worker job location title
Alice soldier Hatchery Grunt
Alice soldier Brood
Chamber
Guard
Alice attendant Brood
Chamber
Feeder
David attendant Brood
Chamber
Midwife
David attendant Pantry Inspector
[
{
‘name’: ‘Alice’,
‘jobs’: [
{
‘name’: ‘soldier’,
‘locations’: [
‘Hatchery’,
‘Brood Chamber’
]
},
{
‘name’: ‘attendant’,
‘locations’: [
‘Brood Chamber’
]
}
]
},
{
‘name’: ‘David’,
‘jobs’: [
{
‘name’: ‘attendant’,
‘locations’: [
‘Brood Chamber’,
‘Pantry’
]
}
]
}
]
Ternary Relationships
• Why can’t we just model this as two m:m relationships
instead?
• What happens if we try to use a BelongsToMany
relationship on a ternary pivot table?
public function jobs()
{
$this->belongsToMany(EloquentTestJob::class, ’assignments',
'worker_id', 'job_id');
}
…
$worker->jobs()->get();
$worker->load(jobs.locations)->get();
Using Two BelongsToMany
// $worker->jobs()->get();
{
'name': 'soldier'
},
{
'name': 'soldier'
},
{
'name': 'attendant'
}
Using Two BelongsToMany
// $worker->load(jobs.locations)->get();
{
'name': 'soldier',
'locations': {
'Hatchery',
'Brood Chamber'
}
},
{
'name': 'soldier',
'locations': {
'Hatchery',
'Brood Chamber'
}
},
{
'name': 'attendant',
'locations': {
'Brood Chamber',
'Brood Chamber',
'Pantry'
}
}
Using BelongsToTernary
// $worker->jobs()->withTertiary(‘locations’)->get();
{
'name': 'soldier',
'locations': {
'Hatchery',
'Brood Chamber'
}
},
{
'name': 'attendant',
'locations': {
'Brood Chamber’
}
}
Goals
• Understand Eloquent’s Model and query builder classes
• Understand how Eloquent implements database relationships
• Understand how Eloquent solves the N+1 problem
• Implement a basic BelongsToTernary relationship
• Implement eager loading for BelongsToTernary
• Implement loading of the tertiary models as a nested
collection
https://github.com/alexweissman/phpworld2017
Architecture of Eloquent
Retrieving a relation on a single model
$user = User::find(1);
$roles = $user->roles()->get();
$users = User::where(‘active’, ‘1’)
->with(‘roles’)
->get();
Retrieving a relation on a collection of models (eager load)
$users = User::where(‘active’, ‘1’)->get();
$users->load(‘roles’);
get() is a method of Relation!
get() is a method of EloquentBuilder!
Need to override this!
Don’t need to
override this.
Retrieving a relation on a single model
select * from `jobs`
inner join `job_workers`
on `job_workers`.`job_id` = `jobs`.`id`
and `job_workers`.`worker_id` = 1
many-to-many
$user = User::find(1);
$emails = $user->emails()->get();
select * from `emails`
where `user_id` = 1
one-to-many
$worker = Worker::find(1);
$jobs = $worker->jobs()->get();
Retrieving a relation on a single model, many-to-many
Stack trace time!
$worker = Worker::find(1);
$jobs = $worker->jobs()->get();
BelongsToMany::performJoin
BelongsToMany::addConstraints
Relation::__construct
BelongsToMany::__construct
Model::belongsToMany
Constructing the query
Assembling the Collection
EloquentBuilder::getModels
BelongsToMany::get
Retrieving a relation on a collection, many-to-many
select * from `workers`;
select * from `jobs`
inner join `job_workers`
on `job_workers`.`job_id` = `jobs`.`id`
and `job_workers`.`worker_id` in (1,2);
many-to-many
$users = User::with(‘emails’)->get();
select * from `users`;
select * from `emails` where `user_id` in (1,2);
one-to-many
$workers = Worker::with(‘jobs’)->get();
Retrieving a relation on a collection, many-to-many
select * from `workers`;
select * from `jobs`
inner join `job_workers`
on `job_workers`.`job_id` = `jobs`.`id`
and `job_workers`.`worker_id` in (1,2);
many-to-many
$users = User::with(‘emails’)->get();
select * from `users`;
select * from `emails` where `user_id` in (1,2);
one-to-many
$workers = Worker::with(‘jobs’)->get();
solves the n+1
problem!
Retrieving a relation on a collection, many-to-many
Stack trace time!
BelongsToMany::performJoin
BelongsToMany::addConstraints
Relation::__construct
BelongsToMany::__construct
Model::belongsToMany
Constructing the query
Assembling the Collection
Relation::getEager
BelongsToMany::match
EloquentBuilder::eagerLoadRelation
EloquentBuilder::eagerLoadRelations
EloquentBuilder::get
$workers = Worker::with(‘jobs’)->get();
match
Alice
David
$models
(from main EloquentBuilder)
row1
$results
(from the joined query in BelongsToMany)
row2
row3
row4
row5
buildDictionary
Alice
David
$models
(from main EloquentBuilder)
row1
$results
(from the joined query in BelongsToMany)
row2
row3
row4
row5
Task 1
Implement BelongsToTernary::condenseModels,
which collapses these rows into a single model.
For now, don't worry about extracting the
tertiary models (locations) for the sub-
relationship.
Task 2
Modify BelongsToTernary::match, which is
responsible for matching eager-loaded models
to their parents.
Again, we have provided you with the default
implementation from BelongsToMany::match,
but you must modify it to collapse rows with the
same worker_id and job_id (for example) into a
single child model.
Task 3
By default, BelongsToTernary::buildDictionary returns a dictionary that maps parent models to their
children. Modify it so that it also returns a nestedDictionary, which maps parent->child->tertiary
models.
For example:
[
// Worker 1
'1' => [
// Job 3
'3' => [
Location1,
Location2
],
...
],
...
]
You will also need to further modify condenseModels to retrieve the tertiary dictionary and call
matchTertiaryModels to match the tertiary models with each of the child models, if withTertiary is being
used.
Try this at home
BelongsToManyThrough
$user->permissions()->get();
User m:m Role m:m Permission
Full implementations in https://github.com/userfrosting/UserFrosting

More Related Content

What's hot

SSIとDIDで何を解決したいのか?(β版)
SSIとDIDで何を解決したいのか?(β版)SSIとDIDで何を解決したいのか?(β版)
SSIとDIDで何を解決したいのか?(β版)Naohiro Fujie
 
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Masahito Zembutsu
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Ryosuke Uchitate
 
What's new in Spring Batch 5
What's new in Spring Batch 5What's new in Spring Batch 5
What's new in Spring Batch 5ikeyat
 
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~Masahito Zembutsu
 
CircleCIのinfrastructureを支えるTerraformのCI/CDパイプラインの改善
CircleCIのinfrastructureを支えるTerraformのCI/CDパイプラインの改善CircleCIのinfrastructureを支えるTerraformのCI/CDパイプラインの改善
CircleCIのinfrastructureを支えるTerraformのCI/CDパイプラインの改善Ito Takayuki
 
Docker入門: コンテナ型仮想化技術の仕組みと使い方
Docker入門: コンテナ型仮想化技術の仕組みと使い方Docker入門: コンテナ型仮想化技術の仕組みと使い方
Docker入門: コンテナ型仮想化技術の仕組みと使い方Yuichi Ito
 
グリーのセキュリティ戦略:組織改革成功の秘訣と新たな課題への取り組み
グリーのセキュリティ戦略:組織改革成功の秘訣と新たな課題への取り組みグリーのセキュリティ戦略:組織改革成功の秘訣と新たな課題への取り組み
グリーのセキュリティ戦略:組織改革成功の秘訣と新たな課題への取り組みgree_tech
 
MicrosoftのDID/VC実装概要
MicrosoftのDID/VC実装概要MicrosoftのDID/VC実装概要
MicrosoftのDID/VC実装概要Naohiro Fujie
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021Hiroshi Tokumaru
 
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割Recruit Lifestyle Co., Ltd.
 
忙しい人の5分で分かるDocker 2017年春Ver
忙しい人の5分で分かるDocker 2017年春Ver忙しい人の5分で分かるDocker 2017年春Ver
忙しい人の5分で分かるDocker 2017年春VerMasahito Zembutsu
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法Tetsutaro Watanabe
 
ZabbixのAPIを使って運用を楽しくする話
ZabbixのAPIを使って運用を楽しくする話ZabbixのAPIを使って運用を楽しくする話
ZabbixのAPIを使って運用を楽しくする話Masahito Zembutsu
 
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetupこれで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線MeetupMasatoshi Tada
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with KarateTakanori Suzuki
 

What's hot (20)

SSIとDIDで何を解決したいのか?(β版)
SSIとDIDで何を解決したいのか?(β版)SSIとDIDで何を解決したいのか?(β版)
SSIとDIDで何を解決したいのか?(β版)
 
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門
 
What's new in Spring Batch 5
What's new in Spring Batch 5What's new in Spring Batch 5
What's new in Spring Batch 5
 
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
 
CircleCIのinfrastructureを支えるTerraformのCI/CDパイプラインの改善
CircleCIのinfrastructureを支えるTerraformのCI/CDパイプラインの改善CircleCIのinfrastructureを支えるTerraformのCI/CDパイプラインの改善
CircleCIのinfrastructureを支えるTerraformのCI/CDパイプラインの改善
 
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_cccSpring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
 
Docker入門: コンテナ型仮想化技術の仕組みと使い方
Docker入門: コンテナ型仮想化技術の仕組みと使い方Docker入門: コンテナ型仮想化技術の仕組みと使い方
Docker入門: コンテナ型仮想化技術の仕組みと使い方
 
グリーのセキュリティ戦略:組織改革成功の秘訣と新たな課題への取り組み
グリーのセキュリティ戦略:組織改革成功の秘訣と新たな課題への取り組みグリーのセキュリティ戦略:組織改革成功の秘訣と新たな課題への取り組み
グリーのセキュリティ戦略:組織改革成功の秘訣と新たな課題への取り組み
 
MicrosoftのDID/VC実装概要
MicrosoftのDID/VC実装概要MicrosoftのDID/VC実装概要
MicrosoftのDID/VC実装概要
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
 
忙しい人の5分で分かるDocker 2017年春Ver
忙しい人の5分で分かるDocker 2017年春Ver忙しい人の5分で分かるDocker 2017年春Ver
忙しい人の5分で分かるDocker 2017年春Ver
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
入門 シェル実装
入門 シェル実装入門 シェル実装
入門 シェル実装
 
MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法
 
ZabbixのAPIを使って運用を楽しくする話
ZabbixのAPIを使って運用を楽しくする話ZabbixのAPIを使って運用を楽しくする話
ZabbixのAPIを使って運用を楽しくする話
 
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetupこれで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate
 
Kubernetes
KubernetesKubernetes
Kubernetes
 

Similar to Hacking Laravel - Custom Relationships with Eloquent

Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Colin O'Dell
 
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Colin O'Dell
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsIgnacio Martín
 
Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Tomasz Dziuda
 
Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Colin O'Dell
 
JSON SQL Injection and the Lessons Learned
JSON SQL Injection and the Lessons LearnedJSON SQL Injection and the Lessons Learned
JSON SQL Injection and the Lessons LearnedKazuho Oku
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-onAndrea Valenza
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?Fabio Kung
 
Três conceitos que farão a diferença nos seus apps
Três conceitos que farão a diferença nos seus appsTrês conceitos que farão a diferença nos seus apps
Três conceitos que farão a diferença nos seus appsGuilherme Rambo
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 

Similar to Hacking Laravel - Custom Relationships with Eloquent (20)

Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016
 
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
 
Python: Basic Inheritance
Python: Basic InheritancePython: Basic Inheritance
Python: Basic Inheritance
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Why Our Code Smells
Why Our Code SmellsWhy Our Code Smells
Why Our Code Smells
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015
 
Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016
 
JSON SQL Injection and the Lessons Learned
JSON SQL Injection and the Lessons LearnedJSON SQL Injection and the Lessons Learned
JSON SQL Injection and the Lessons Learned
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-on
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?
 
Três conceitos que farão a diferença nos seus apps
Três conceitos que farão a diferença nos seus appsTrês conceitos que farão a diferença nos seus apps
Três conceitos que farão a diferença nos seus apps
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 

Recently uploaded

How is AI changing journalism? (v. April 2024)
How is AI changing journalism? (v. April 2024)How is AI changing journalism? (v. April 2024)
How is AI changing journalism? (v. April 2024)Damian Radcliffe
 
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607dollysharma2066
 
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...APNIC
 
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130  Available With RoomVIP Kolkata Call Girl Alambazar 👉 8250192130  Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Roomdivyansh0kumar0
 
Networking in the Penumbra presented by Geoff Huston at NZNOG
Networking in the Penumbra presented by Geoff Huston at NZNOGNetworking in the Penumbra presented by Geoff Huston at NZNOG
Networking in the Penumbra presented by Geoff Huston at NZNOGAPNIC
 
VIP Kolkata Call Girl Kestopur 👉 8250192130 Available With Room
VIP Kolkata Call Girl Kestopur 👉 8250192130  Available With RoomVIP Kolkata Call Girl Kestopur 👉 8250192130  Available With Room
VIP Kolkata Call Girl Kestopur 👉 8250192130 Available With Roomdivyansh0kumar0
 
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls KolkataLow Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebGDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebJames Anderson
 
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on DeliveryCall Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Deliverybabeytanya
 
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With RoomVIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Roomgirls4nights
 
VIP Call Girls Pune Madhuri 8617697112 Independent Escort Service Pune
VIP Call Girls Pune Madhuri 8617697112 Independent Escort Service PuneVIP Call Girls Pune Madhuri 8617697112 Independent Escort Service Pune
VIP Call Girls Pune Madhuri 8617697112 Independent Escort Service PuneCall girls in Ahmedabad High profile
 
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...Diya Sharma
 
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxAWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxellan12
 
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call GirlVIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girladitipandeya
 
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024APNIC
 
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Delhi Call girls
 
On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024APNIC
 

Recently uploaded (20)

How is AI changing journalism? (v. April 2024)
How is AI changing journalism? (v. April 2024)How is AI changing journalism? (v. April 2024)
How is AI changing journalism? (v. April 2024)
 
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
 
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
'Future Evolution of the Internet' delivered by Geoff Huston at Everything Op...
 
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130  Available With RoomVIP Kolkata Call Girl Alambazar 👉 8250192130  Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
 
Networking in the Penumbra presented by Geoff Huston at NZNOG
Networking in the Penumbra presented by Geoff Huston at NZNOGNetworking in the Penumbra presented by Geoff Huston at NZNOG
Networking in the Penumbra presented by Geoff Huston at NZNOG
 
VIP Kolkata Call Girl Kestopur 👉 8250192130 Available With Room
VIP Kolkata Call Girl Kestopur 👉 8250192130  Available With RoomVIP Kolkata Call Girl Kestopur 👉 8250192130  Available With Room
VIP Kolkata Call Girl Kestopur 👉 8250192130 Available With Room
 
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls KolkataLow Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No AdvanceRohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
 
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebGDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
 
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
 
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on DeliveryCall Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
 
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No AdvanceRohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
 
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With RoomVIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
 
VIP Call Girls Pune Madhuri 8617697112 Independent Escort Service Pune
VIP Call Girls Pune Madhuri 8617697112 Independent Escort Service PuneVIP Call Girls Pune Madhuri 8617697112 Independent Escort Service Pune
VIP Call Girls Pune Madhuri 8617697112 Independent Escort Service Pune
 
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
 
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxAWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
 
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call GirlVIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
 
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
DDoS In Oceania and the Pacific, presented by Dave Phelan at NZNOG 2024
 
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
 
On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024
 

Hacking Laravel - Custom Relationships with Eloquent

  • 1. Hacking Laravel Custom relationships with Eloquent Alex Weissman https://chat.userfrosting.com @userfrosting
  • 2. Basic Relationships student subject Alice Freestyling Alice Beatboxing David Beatboxing David Turntabling name team Alice London David Liverpool Abdullah London person partner Alice David Abdullah Louis Model::hasOne Model::hasMany Model::belongsToMany
  • 4. Ternary Relationships worker job location title Alice soldier Hatchery Grunt Alice soldier Brood Chamber Guard Alice attendant Brood Chamber Feeder David attendant Brood Chamber Midwife David attendant Pantry Inspector [ { ‘name’: ‘Alice’, ‘jobs’: [ { ‘name’: ‘soldier’, ‘locations’: [ ‘Hatchery’, ‘Brood Chamber’ ] }, { ‘name’: ‘attendant’, ‘locations’: [ ‘Brood Chamber’ ] } ] }, { ‘name’: ‘David’, ‘jobs’: [ { ‘name’: ‘attendant’, ‘locations’: [ ‘Brood Chamber’, ‘Pantry’ ] } ] } ]
  • 5. Ternary Relationships • Why can’t we just model this as two m:m relationships instead? • What happens if we try to use a BelongsToMany relationship on a ternary pivot table? public function jobs() { $this->belongsToMany(EloquentTestJob::class, ’assignments', 'worker_id', 'job_id'); } … $worker->jobs()->get(); $worker->load(jobs.locations)->get();
  • 6. Using Two BelongsToMany // $worker->jobs()->get(); { 'name': 'soldier' }, { 'name': 'soldier' }, { 'name': 'attendant' }
  • 7. Using Two BelongsToMany // $worker->load(jobs.locations)->get(); { 'name': 'soldier', 'locations': { 'Hatchery', 'Brood Chamber' } }, { 'name': 'soldier', 'locations': { 'Hatchery', 'Brood Chamber' } }, { 'name': 'attendant', 'locations': { 'Brood Chamber', 'Brood Chamber', 'Pantry' } }
  • 8. Using BelongsToTernary // $worker->jobs()->withTertiary(‘locations’)->get(); { 'name': 'soldier', 'locations': { 'Hatchery', 'Brood Chamber' } }, { 'name': 'attendant', 'locations': { 'Brood Chamber’ } }
  • 9. Goals • Understand Eloquent’s Model and query builder classes • Understand how Eloquent implements database relationships • Understand how Eloquent solves the N+1 problem • Implement a basic BelongsToTernary relationship • Implement eager loading for BelongsToTernary • Implement loading of the tertiary models as a nested collection https://github.com/alexweissman/phpworld2017
  • 11. Retrieving a relation on a single model $user = User::find(1); $roles = $user->roles()->get(); $users = User::where(‘active’, ‘1’) ->with(‘roles’) ->get(); Retrieving a relation on a collection of models (eager load) $users = User::where(‘active’, ‘1’)->get(); $users->load(‘roles’); get() is a method of Relation! get() is a method of EloquentBuilder! Need to override this! Don’t need to override this.
  • 12. Retrieving a relation on a single model select * from `jobs` inner join `job_workers` on `job_workers`.`job_id` = `jobs`.`id` and `job_workers`.`worker_id` = 1 many-to-many $user = User::find(1); $emails = $user->emails()->get(); select * from `emails` where `user_id` = 1 one-to-many $worker = Worker::find(1); $jobs = $worker->jobs()->get();
  • 13. Retrieving a relation on a single model, many-to-many Stack trace time! $worker = Worker::find(1); $jobs = $worker->jobs()->get(); BelongsToMany::performJoin BelongsToMany::addConstraints Relation::__construct BelongsToMany::__construct Model::belongsToMany Constructing the query Assembling the Collection EloquentBuilder::getModels BelongsToMany::get
  • 14. Retrieving a relation on a collection, many-to-many select * from `workers`; select * from `jobs` inner join `job_workers` on `job_workers`.`job_id` = `jobs`.`id` and `job_workers`.`worker_id` in (1,2); many-to-many $users = User::with(‘emails’)->get(); select * from `users`; select * from `emails` where `user_id` in (1,2); one-to-many $workers = Worker::with(‘jobs’)->get();
  • 15. Retrieving a relation on a collection, many-to-many select * from `workers`; select * from `jobs` inner join `job_workers` on `job_workers`.`job_id` = `jobs`.`id` and `job_workers`.`worker_id` in (1,2); many-to-many $users = User::with(‘emails’)->get(); select * from `users`; select * from `emails` where `user_id` in (1,2); one-to-many $workers = Worker::with(‘jobs’)->get(); solves the n+1 problem!
  • 16. Retrieving a relation on a collection, many-to-many Stack trace time! BelongsToMany::performJoin BelongsToMany::addConstraints Relation::__construct BelongsToMany::__construct Model::belongsToMany Constructing the query Assembling the Collection Relation::getEager BelongsToMany::match EloquentBuilder::eagerLoadRelation EloquentBuilder::eagerLoadRelations EloquentBuilder::get $workers = Worker::with(‘jobs’)->get();
  • 17. match Alice David $models (from main EloquentBuilder) row1 $results (from the joined query in BelongsToMany) row2 row3 row4 row5
  • 18. buildDictionary Alice David $models (from main EloquentBuilder) row1 $results (from the joined query in BelongsToMany) row2 row3 row4 row5
  • 19. Task 1 Implement BelongsToTernary::condenseModels, which collapses these rows into a single model. For now, don't worry about extracting the tertiary models (locations) for the sub- relationship.
  • 20. Task 2 Modify BelongsToTernary::match, which is responsible for matching eager-loaded models to their parents. Again, we have provided you with the default implementation from BelongsToMany::match, but you must modify it to collapse rows with the same worker_id and job_id (for example) into a single child model.
  • 21. Task 3 By default, BelongsToTernary::buildDictionary returns a dictionary that maps parent models to their children. Modify it so that it also returns a nestedDictionary, which maps parent->child->tertiary models. For example: [ // Worker 1 '1' => [ // Job 3 '3' => [ Location1, Location2 ], ... ], ... ] You will also need to further modify condenseModels to retrieve the tertiary dictionary and call matchTertiaryModels to match the tertiary models with each of the child models, if withTertiary is being used.
  • 22. Try this at home BelongsToManyThrough $user->permissions()->get(); User m:m Role m:m Permission Full implementations in https://github.com/userfrosting/UserFrosting