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

MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法Tetsutaro Watanabe
 
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり Rakuten Group, Inc.
 
BloodHound 1.3 - The ACL Attack Path Update - Paranoia17, Oslo
BloodHound 1.3 - The ACL Attack Path Update - Paranoia17, OsloBloodHound 1.3 - The ACL Attack Path Update - Paranoia17, Oslo
BloodHound 1.3 - The ACL Attack Path Update - Paranoia17, OsloAndy Robbins
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)Takuto Wada
 
RDBNoSQLの基礎と組み合わせDB構成をちょっとよくする話
RDBNoSQLの基礎と組み合わせDB構成をちょっとよくする話RDBNoSQLの基礎と組み合わせDB構成をちょっとよくする話
RDBNoSQLの基礎と組み合わせDB構成をちょっとよくする話Shohei Kobayashi
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
Redmineをプラグインで拡張しよう
Redmineをプラグインで拡張しようRedmineをプラグインで拡張しよう
Redmineをプラグインで拡張しようHaruyuki Iida
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターンSoudai Sone
 
クリーンアーキテクチャの考え方にもとづく Laravel との付き合い方 #phpconokinawa
クリーンアーキテクチャの考え方にもとづく Laravel との付き合い方 #phpconokinawaクリーンアーキテクチャの考え方にもとづく Laravel との付き合い方 #phpconokinawa
クリーンアーキテクチャの考え方にもとづく Laravel との付き合い方 #phpconokinawaShohei Okada
 
Rust system programming language
Rust system programming languageRust system programming language
Rust system programming languagerobin_sy
 
"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy"Simple Made Easy" Made Easy
"Simple Made Easy" Made EasyKent Ohashi
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析mametter
 
Pentest Application With GraphQL | Null Bangalore Meetup
Pentest Application With GraphQL | Null Bangalore Meetup Pentest Application With GraphQL | Null Bangalore Meetup
Pentest Application With GraphQL | Null Bangalore Meetup Divyanshu
 
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) Hironobu Isoda
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装infinite_loop
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 

What's hot (20)

MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法
 
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
 
BloodHound 1.3 - The ACL Attack Path Update - Paranoia17, Oslo
BloodHound 1.3 - The ACL Attack Path Update - Paranoia17, OsloBloodHound 1.3 - The ACL Attack Path Update - Paranoia17, Oslo
BloodHound 1.3 - The ACL Attack Path Update - Paranoia17, Oslo
 
Java script ppt
Java script pptJava script ppt
Java script ppt
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
RDBNoSQLの基礎と組み合わせDB構成をちょっとよくする話
RDBNoSQLの基礎と組み合わせDB構成をちょっとよくする話RDBNoSQLの基礎と組み合わせDB構成をちょっとよくする話
RDBNoSQLの基礎と組み合わせDB構成をちょっとよくする話
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
Redmineをプラグインで拡張しよう
Redmineをプラグインで拡張しようRedmineをプラグインで拡張しよう
Redmineをプラグインで拡張しよう
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターン
 
クリーンアーキテクチャの考え方にもとづく Laravel との付き合い方 #phpconokinawa
クリーンアーキテクチャの考え方にもとづく Laravel との付き合い方 #phpconokinawaクリーンアーキテクチャの考え方にもとづく Laravel との付き合い方 #phpconokinawa
クリーンアーキテクチャの考え方にもとづく Laravel との付き合い方 #phpconokinawa
 
Rust system programming language
Rust system programming languageRust system programming language
Rust system programming language
 
"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
 
Go入門
Go入門Go入門
Go入門
 
Pentest Application With GraphQL | Null Bangalore Meetup
Pentest Application With GraphQL | Null Bangalore Meetup Pentest Application With GraphQL | Null Bangalore Meetup
Pentest Application With GraphQL | Null Bangalore Meetup
 
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 

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

定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一Fs
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一z xss
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhimiss dipika
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书zdzoqco
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Excelmac1
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITMgdsc13
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Sonam Pathan
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa494f574xmv
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predieusebiomeyer
 
Q4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxQ4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxeditsforyah
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Sonam Pathan
 
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一Fs
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书rnrncn29
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作ys8omjxb
 
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书rnrncn29
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMartaLoveguard
 
Elevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New OrleansElevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New Orleanscorenetworkseo
 
NSX-T and Service Interfaces presentation
NSX-T and Service Interfaces presentationNSX-T and Service Interfaces presentation
NSX-T and Service Interfaces presentationMarko4394
 

Recently uploaded (20)

定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhi
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITM
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predi
 
Q4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxQ4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptx
 
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
 
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
 
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptx
 
Elevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New OrleansElevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New Orleans
 
NSX-T and Service Interfaces presentation
NSX-T and Service Interfaces presentationNSX-T and Service Interfaces presentation
NSX-T and Service Interfaces presentation
 

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