SlideShare a Scribd company logo
1 of 22
Download to read offline
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

Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Scott Wlaschin
 
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)Koichiro Matsuoka
 
がっつりMongoDB事例紹介
がっつりMongoDB事例紹介がっつりMongoDB事例紹介
がっつりMongoDB事例紹介Tetsutaro Watanabe
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
ビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分けビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分けRecruit Technologies
 
ソーシャルゲームの為のデータベース設計
ソーシャルゲームの為のデータベース設計ソーシャルゲームの為のデータベース設計
ソーシャルゲームの為のデータベース設計kaminashi
 
PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)
PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)
PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)NTT DATA Technology & Innovation
 
Dominoアクセスサービスを使用したRESTサービスのプレイブック
Dominoアクセスサービスを使用したRESTサービスのプレイブックDominoアクセスサービスを使用したRESTサービスのプレイブック
Dominoアクセスサービスを使用したRESTサービスのプレイブックMitsuru Katoh
 
[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...
[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...
[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...Insight Technology, Inc.
 
MongoDB〜その性質と利用場面〜
MongoDB〜その性質と利用場面〜MongoDB〜その性質と利用場面〜
MongoDB〜その性質と利用場面〜Naruhiko Ogasawara
 
Laravel × レイヤードアーキテクチャを実践して得られた知見と反省 / Practice of Laravel with layered archi...
Laravel × レイヤードアーキテクチャを実践して得られた知見と反省 / Practice of Laravel with layered archi...Laravel × レイヤードアーキテクチャを実践して得られた知見と反省 / Practice of Laravel with layered archi...
Laravel × レイヤードアーキテクチャを実践して得られた知見と反省 / Practice of Laravel with layered archi...Shohei Okada
 
AWSとReactで始めるShopifyアプリ開発
AWSとReactで始めるShopifyアプリ開発AWSとReactで始めるShopifyアプリ開発
AWSとReactで始めるShopifyアプリ開発Takaaki Kurasawa
 
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介IBM Analytics Japan
 
なぜOpenID Connectが必要となったのか、その歴史的背景
なぜOpenID Connectが必要となったのか、その歴史的背景なぜOpenID Connectが必要となったのか、その歴史的背景
なぜOpenID Connectが必要となったのか、その歴史的背景Tatsuo Kudo
 
redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바NeoClova
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニングyoku0825
 
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #1320210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13Amazon Web Services Japan
 

What's hot (20)

Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
 
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
 
がっつりMongoDB事例紹介
がっつりMongoDB事例紹介がっつりMongoDB事例紹介
がっつりMongoDB事例紹介
 
CSP Lv.2の話
CSP Lv.2の話CSP Lv.2の話
CSP Lv.2の話
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
ビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分けビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分け
 
ソーシャルゲームの為のデータベース設計
ソーシャルゲームの為のデータベース設計ソーシャルゲームの為のデータベース設計
ソーシャルゲームの為のデータベース設計
 
Sql基礎の基礎
Sql基礎の基礎Sql基礎の基礎
Sql基礎の基礎
 
PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)
PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)
PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)
 
Dominoアクセスサービスを使用したRESTサービスのプレイブック
Dominoアクセスサービスを使用したRESTサービスのプレイブックDominoアクセスサービスを使用したRESTサービスのプレイブック
Dominoアクセスサービスを使用したRESTサービスのプレイブック
 
[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...
[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...
[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...
 
MongoDB〜その性質と利用場面〜
MongoDB〜その性質と利用場面〜MongoDB〜その性質と利用場面〜
MongoDB〜その性質と利用場面〜
 
Laravel × レイヤードアーキテクチャを実践して得られた知見と反省 / Practice of Laravel with layered archi...
Laravel × レイヤードアーキテクチャを実践して得られた知見と反省 / Practice of Laravel with layered archi...Laravel × レイヤードアーキテクチャを実践して得られた知見と反省 / Practice of Laravel with layered archi...
Laravel × レイヤードアーキテクチャを実践して得られた知見と反省 / Practice of Laravel with layered archi...
 
AWSとReactで始めるShopifyアプリ開発
AWSとReactで始めるShopifyアプリ開発AWSとReactで始めるShopifyアプリ開発
AWSとReactで始めるShopifyアプリ開発
 
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介
 
なぜOpenID Connectが必要となったのか、その歴史的背景
なぜOpenID Connectが必要となったのか、その歴史的背景なぜOpenID Connectが必要となったのか、その歴史的背景
なぜOpenID Connectが必要となったのか、その歴史的背景
 
redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
 
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #1320210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
 

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

Introduction to ICANN and Fellowship program by Shreedeep Rayamajhi.pdf
Introduction to ICANN and Fellowship program  by Shreedeep Rayamajhi.pdfIntroduction to ICANN and Fellowship program  by Shreedeep Rayamajhi.pdf
Introduction to ICANN and Fellowship program by Shreedeep Rayamajhi.pdfShreedeep Rayamajhi
 
Presentation2.pptx - JoyPress Wordpress
Presentation2.pptx -  JoyPress WordpressPresentation2.pptx -  JoyPress Wordpress
Presentation2.pptx - JoyPress Wordpressssuser166378
 
world Tuberculosis day ppt 25-3-2024.pptx
world Tuberculosis day ppt 25-3-2024.pptxworld Tuberculosis day ppt 25-3-2024.pptx
world Tuberculosis day ppt 25-3-2024.pptxnaveenithkrishnan
 
Check out the Free Landing Page Hosting in 2024
Check out the Free Landing Page Hosting in 2024Check out the Free Landing Page Hosting in 2024
Check out the Free Landing Page Hosting in 2024Shubham Pant
 
LESSON 5 GROUP 10 ST. THOMAS AQUINAS.pdf
LESSON 5 GROUP 10 ST. THOMAS AQUINAS.pdfLESSON 5 GROUP 10 ST. THOMAS AQUINAS.pdf
LESSON 5 GROUP 10 ST. THOMAS AQUINAS.pdfmchristianalwyn
 
LESSON 10/ GROUP 10/ ST. THOMAS AQUINASS
LESSON 10/ GROUP 10/ ST. THOMAS AQUINASSLESSON 10/ GROUP 10/ ST. THOMAS AQUINASS
LESSON 10/ GROUP 10/ ST. THOMAS AQUINASSlesteraporado16
 
TYPES AND DEFINITION OF ONLINE CRIMES AND HAZARDS
TYPES AND DEFINITION OF ONLINE CRIMES AND HAZARDSTYPES AND DEFINITION OF ONLINE CRIMES AND HAZARDS
TYPES AND DEFINITION OF ONLINE CRIMES AND HAZARDSedrianrheine
 
Niche Domination Prodigy Review Plus Bonus
Niche Domination Prodigy Review Plus BonusNiche Domination Prodigy Review Plus Bonus
Niche Domination Prodigy Review Plus BonusSkylark Nobin
 
Zero-day Vulnerabilities
Zero-day VulnerabilitiesZero-day Vulnerabilities
Zero-day Vulnerabilitiesalihassaah1994
 
Benefits of doing Internet peering and running an Internet Exchange (IX) pres...
Benefits of doing Internet peering and running an Internet Exchange (IX) pres...Benefits of doing Internet peering and running an Internet Exchange (IX) pres...
Benefits of doing Internet peering and running an Internet Exchange (IX) pres...APNIC
 
Computer 10 Lesson 8: Building a Website
Computer 10 Lesson 8: Building a WebsiteComputer 10 Lesson 8: Building a Website
Computer 10 Lesson 8: Building a WebsiteMavein
 
A_Z-1_0_4T_00A-EN_U-Po_w_erPoint_06.pptx
A_Z-1_0_4T_00A-EN_U-Po_w_erPoint_06.pptxA_Z-1_0_4T_00A-EN_U-Po_w_erPoint_06.pptx
A_Z-1_0_4T_00A-EN_U-Po_w_erPoint_06.pptxjayshuklatrainer
 
Bio Medical Waste Management Guideliness 2023 ppt.pptx
Bio Medical Waste Management Guideliness 2023 ppt.pptxBio Medical Waste Management Guideliness 2023 ppt.pptx
Bio Medical Waste Management Guideliness 2023 ppt.pptxnaveenithkrishnan
 
Vision Forward: Tracing Image Search SEO From Its Roots To AI-Enhanced Horizons
Vision Forward: Tracing Image Search SEO From Its Roots To AI-Enhanced HorizonsVision Forward: Tracing Image Search SEO From Its Roots To AI-Enhanced Horizons
Vision Forward: Tracing Image Search SEO From Its Roots To AI-Enhanced HorizonsRoxana Stingu
 
WordPress by the numbers - Jan Loeffler, CTO WebPros, CloudFest 2024
WordPress by the numbers - Jan Loeffler, CTO WebPros, CloudFest 2024WordPress by the numbers - Jan Loeffler, CTO WebPros, CloudFest 2024
WordPress by the numbers - Jan Loeffler, CTO WebPros, CloudFest 2024Jan Löffler
 

Recently uploaded (15)

Introduction to ICANN and Fellowship program by Shreedeep Rayamajhi.pdf
Introduction to ICANN and Fellowship program  by Shreedeep Rayamajhi.pdfIntroduction to ICANN and Fellowship program  by Shreedeep Rayamajhi.pdf
Introduction to ICANN and Fellowship program by Shreedeep Rayamajhi.pdf
 
Presentation2.pptx - JoyPress Wordpress
Presentation2.pptx -  JoyPress WordpressPresentation2.pptx -  JoyPress Wordpress
Presentation2.pptx - JoyPress Wordpress
 
world Tuberculosis day ppt 25-3-2024.pptx
world Tuberculosis day ppt 25-3-2024.pptxworld Tuberculosis day ppt 25-3-2024.pptx
world Tuberculosis day ppt 25-3-2024.pptx
 
Check out the Free Landing Page Hosting in 2024
Check out the Free Landing Page Hosting in 2024Check out the Free Landing Page Hosting in 2024
Check out the Free Landing Page Hosting in 2024
 
LESSON 5 GROUP 10 ST. THOMAS AQUINAS.pdf
LESSON 5 GROUP 10 ST. THOMAS AQUINAS.pdfLESSON 5 GROUP 10 ST. THOMAS AQUINAS.pdf
LESSON 5 GROUP 10 ST. THOMAS AQUINAS.pdf
 
LESSON 10/ GROUP 10/ ST. THOMAS AQUINASS
LESSON 10/ GROUP 10/ ST. THOMAS AQUINASSLESSON 10/ GROUP 10/ ST. THOMAS AQUINASS
LESSON 10/ GROUP 10/ ST. THOMAS AQUINASS
 
TYPES AND DEFINITION OF ONLINE CRIMES AND HAZARDS
TYPES AND DEFINITION OF ONLINE CRIMES AND HAZARDSTYPES AND DEFINITION OF ONLINE CRIMES AND HAZARDS
TYPES AND DEFINITION OF ONLINE CRIMES AND HAZARDS
 
Niche Domination Prodigy Review Plus Bonus
Niche Domination Prodigy Review Plus BonusNiche Domination Prodigy Review Plus Bonus
Niche Domination Prodigy Review Plus Bonus
 
Zero-day Vulnerabilities
Zero-day VulnerabilitiesZero-day Vulnerabilities
Zero-day Vulnerabilities
 
Benefits of doing Internet peering and running an Internet Exchange (IX) pres...
Benefits of doing Internet peering and running an Internet Exchange (IX) pres...Benefits of doing Internet peering and running an Internet Exchange (IX) pres...
Benefits of doing Internet peering and running an Internet Exchange (IX) pres...
 
Computer 10 Lesson 8: Building a Website
Computer 10 Lesson 8: Building a WebsiteComputer 10 Lesson 8: Building a Website
Computer 10 Lesson 8: Building a Website
 
A_Z-1_0_4T_00A-EN_U-Po_w_erPoint_06.pptx
A_Z-1_0_4T_00A-EN_U-Po_w_erPoint_06.pptxA_Z-1_0_4T_00A-EN_U-Po_w_erPoint_06.pptx
A_Z-1_0_4T_00A-EN_U-Po_w_erPoint_06.pptx
 
Bio Medical Waste Management Guideliness 2023 ppt.pptx
Bio Medical Waste Management Guideliness 2023 ppt.pptxBio Medical Waste Management Guideliness 2023 ppt.pptx
Bio Medical Waste Management Guideliness 2023 ppt.pptx
 
Vision Forward: Tracing Image Search SEO From Its Roots To AI-Enhanced Horizons
Vision Forward: Tracing Image Search SEO From Its Roots To AI-Enhanced HorizonsVision Forward: Tracing Image Search SEO From Its Roots To AI-Enhanced Horizons
Vision Forward: Tracing Image Search SEO From Its Roots To AI-Enhanced Horizons
 
WordPress by the numbers - Jan Loeffler, CTO WebPros, CloudFest 2024
WordPress by the numbers - Jan Loeffler, CTO WebPros, CloudFest 2024WordPress by the numbers - Jan Loeffler, CTO WebPros, CloudFest 2024
WordPress by the numbers - Jan Loeffler, CTO WebPros, CloudFest 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