Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Laravel - Speaking eloquent eloquently

450 views

Published on

In this talk, Stephen talks about working with Eloquent in a manner that it helps you build world class applications

Published in: Technology
  • Be the first to comment

Laravel - Speaking eloquent eloquently

  1. 1. SPEAKING ELOQUENT ELOQUENTLY
  2. 2. Stephen Afam‐Osemene https://stephenafamo.com @StephenAfamO
  3. 3. Thinking Eloquently Accessors & Mutators Scopes Collections Serialization Events & Observers Relationships Mutators OUTLINE
  4. 4. THINKING ELOQUENTLY
  5. 5. THINKING ELOQUENTLY Eloquent is not just a fancy way of specifying the table for the Query Builder
  6. 6. A Model, should enable us retrieve and manipulate EVERY information related to it THINKING ELOQUENTLY
  7. 7. Data manupulation belongs in the Model A model should completely define a unit of DATA THINKING ELOQUENTLY
  8. 8. ACCESSORS & MUTATORS
  9. 9. ACCESSORS Accessors allow us to format our data when we retrieve them
  10. 10. Instead of ACCESSORS $user = User::find(1); echo "http://myapp.com" . $user‐>avatar;
  11. 11. ACCESSORS We do class User extends Model { public function getAvatarAttribute($value) { return "http://myapp.com/" . $value; } }
  12. 12. MUTATORS Mutators allow us to format our data when we set them
  13. 13. Instead of $user‐>name = ucfirst("stephen"); MUTATORS
  14. 14. We do class User extends Model { public function setNameAttribute($value) { $this‐>attributes['name'] = ucfirst($value); } } MUTATORS
  15. 15. SCOPES
  16. 16. SCOPES Scopes are ways for us to store restraints which we can use repeatedly
  17. 17. SCOPES ‐ LOCAL Local scopes are specific to the model. Although, we can always extend the class ;‐﴿
  18. 18. SCOPES ‐ LOCAL Do this once class Developer extends Model { public function scopeSenior($query) { return $query‐>where('yrs_of_exp', '>', 3); } }
  19. 19. SCOPES ‐ LOCAL Use anytime! $senior_devs = AppDeveloper::senior()‐>get()
  20. 20. SCOPES ‐ LOCAL We can accept additional parameters to make our scopes dynamic
  21. 21. SCOPES ‐ LOCAL class Developer extends Model { public function scopeUses($query, $language) { return $query‐>where('language', $language); } } Make it dynamic
  22. 22. SCOPES ‐ LOCAL $php_devs = AppDeveloper::uses('php)‐>get() Use anytime!
  23. 23. SCOPES ‐ GLOBAL We can define a scope that will be applied to all queries by our Model
  24. 24. SCOPES ‐ GLOBAL use IlluminateDatabaseEloquentScope; class VerifiedScope implements Scope { public function apply($builder, $model) { $builder‐>where('verified', true); } } Define the scope
  25. 25. class Developer extends Model { protected static function boot() { parent::boot(); static::addGlobalScope(new VerifiedScope); } } SCOPES ‐ GLOBAL Include the scope
  26. 26. SCOPES ‐ GLOBAL Now all queries from our Developer model will retrieve only verified entries.
  27. 27. SCOPES ‐ GLOBAL // Global scope automatically applied $verified_devs = Developer::get() // Query without the Verified global scope Developer::withoutGlobalScope(VerifiedScope::class)‐>get() // Query without any global scope Developer:: withoutGlobalScopes()‐>get() Define the scope
  28. 28. COLLECTIONS
  29. 29. COLLECTIONS Anytime multiple records are retrieved, it is returned as a COLLECTION of Models
  30. 30. COLLECTIONS Collections are supercharged php arrays. learn about it https://laravel.com/docs/5.4/collections
  31. 31. COLLECTIONS We can define a custom Collection Object to be returned by our model.
  32. 32. COLLECTIONS use IlluminateSupportCollection; class CustomCollection extends Collection { public function additionalMethod($var) { // do something unique } } Define our new collection class
  33. 33. COLLECTIONS Overwrite the newCollection method class Developer extends Model { public function newCollection(array $models = []) { return new CustomCollection($models); } }
  34. 34. SERIALIZATION
  35. 35. SERIALIZATION We can easily convert our Model into an array or JSON of it's attributes
  36. 36. SERIALIZATION Easy! $developer = AppDeveloper ::find(1); // For arrays $developer_array = $develooper‐>toArray(); // For JSON $developer_json = $developer‐>toJson()
  37. 37. Sometimes we need to hide stuff so... SERIALIZATION class User extends Model { protected $hidden = ['age', 'address']; // OR protected $visible = ['company', 'name']; }
  38. 38. Other times we want to access hidden stuff so... SERIALIZATION $user = AppUser::find(1); // maybe when the user is viewing $with_age = $user‐>makeVisible('age')‐>toArray(); // for corporate reasons maybe ˉ_(ツ)_/ˉ $without_company = $user‐>makeHidden('company')‐>toArray;
  39. 39. What if we just want to add stuff? SERIALIZATION class User extends Model { protected $appends = ['birth_year']; public function getIBirthYearAttribute() { return date("Y") ‐ $this‐>age; } }
  40. 40. EVENTS & OBSERVERS
  41. 41. EVENTS & OBSERVERS Laravel events are a great way to subscribe and listen for various events that occur in our application. https://laravel.com/docs/5.4/events
  42. 42. EVENTS & OBSERVERS Eloquent models fire several events. We can map these events to our event classes
  43. 43. EVENTS & OBSERVERS Define the events property to map events class User extends Model { protected $events = [ 'saved' => UserSaved::class, 'deleted' => UserDeleted::class, ]; }
  44. 44. EVENTS & OBSERVERS Full list of Eloquent events creating created updating updated saving saved deleting deleted restoring restored
  45. 45. EVENTS & OBSERVERS Observers are classes whose sole purpose is to listen to eloquent events
  46. 46. EVENTS & OBSERVERS Create the Observer class use AppMeetup; class MeetupObserver { public function saving (Meetup $meetup) { // do something for the 'saving' event // you an have more functions with 'event' names } }
  47. 47. EVENTS & OBSERVERS Register the observer in a ServiceProvider use AppMeetup; class MyServiceProvider { public function boot () { Meetup::observe(MeetupObserver::class); } }
  48. 48. RELATIONSHIPS
  49. 49. RELATIONSHIPS Eloquent makes is really easy to define and access related models
  50. 50. RELATIONSHIPS ‐ 1‐1 One‐to‐One relationships are where each model is tied to one of the other type
  51. 51. users id ‐ integer name ‐ string contact id ‐ integer user_id ‐ integer phone ‐ string email ‐ string website ‐ string Example Database schema RELATIONSHIPS ‐ 1‐1
  52. 52. Defining one side of the relationship class User extends Model { public function contact() { return $this‐>hasOne('AppContact'); } } RELATIONSHIPS ‐ 1‐1
  53. 53. Defining the other side class Contact extends Model { public function user() { return $this‐>belongsTo('AppUser'); } } RELATIONSHIPS ‐ 1‐1
  54. 54. $user = AppUser::find(1); // Instead of $contact = AppContact::select('contacts.*') ‐>where('user_id', '=', $user‐>id) ‐>first(); // We do $contact = $user‐>contact; RELATIONSHIPS ‐ 1‐1
  55. 55. RELATIONSHIPS ‐ 1‐n One‐to‐Many relationships are where one model is linked to many of another type
  56. 56. Example Database schema users id ‐ integer name ‐ string contact id ‐ integer user_id ‐ integer type ‐ string value ‐ string RELATIONSHIPS ‐ 1‐n
  57. 57. Defining one side of the relationship class User extends Model { public function contacts() { return $this‐>hasMany('AppContact'); } } RELATIONSHIPS ‐ 1‐n
  58. 58. Defining the other side class Contact extends Model { public function user() { return $this‐>belongsTo('AppUser'); } } RELATIONSHIPS ‐ 1‐n
  59. 59. RELATIONSHIPS ‐ 1‐n $user = AppUser::find(1); // Instead of $contacts = AppContact::select('contacts.*') ‐>where('user_id', '=', $user‐>id) ‐>get(); // We do $contacts = $user‐>contacts;
  60. 60. RELATIONSHIPS ‐ n‐n Many‐to‐Many relationships are more complicated
  61. 61. Example Database schema users id ‐ integer name ‐ string contact id ‐ integer user_id ‐ integer type_id ‐ integer value ‐ string type id ‐ integer name ‐ string RELATIONSHIPS ‐ n‐n
  62. 62. Defining one side of the relationship class User extends Model { public function types() { return $this‐>belongsToMany('AppType') ‐>withPivot('id', 'value'); } } RELATIONSHIPS ‐ n‐n
  63. 63. Defining the other side class Type extends Model { public function users() { return $this‐>belongsToMany('AppUser'); } } RELATIONSHIPS ‐ n‐n
  64. 64. RELATIONSHIPS ‐ 1‐n // Instead of $contacts = AppContact::select('contacts.*') ‐>join('types', 'contact.type_id', '=', 'types.id') ‐>where('user_id', '=', $user‐>id) ‐>where('type.name', '=', 'phone') ‐>get(); // We do $types = $user‐>types; //access throught the pivot property
  65. 65. RELATIONSHIPS ‐ distant Distant relations can be accessed easily by using the hasManyThrough﴾﴿ relationship
  66. 66. Example Database schema users id ‐ integer name ‐ string posts id ‐ integer user_id ‐ integer title ‐ string body ‐ string comments id ‐ integer post_id ‐ integer title ‐ string body ‐ string RELATIONSHIPS ‐ distant
  67. 67. Defining the relationship class User extends Model { public function comments() { return $this‐>hasManyThrough('AppPost', 'AppComment); } } RELATIONSHIPS ‐ distant
  68. 68. // Instead of $comments = AppComment::select('comments.*') ‐>join('posts', 'comment.post_id', '=', 'posts.id') ‐>join('users', 'post.user_id', '=', 'users.id') ‐>where('user_id', '=', $user‐>id) ‐>get(); // We do $comments = $user‐>comments; RELATIONSHIPS ‐ distant
  69. 69. RELATIONSHIPS ‐ morph Polymorphic relationships can save us from creating many similar tables.
  70. 70. RELATIONSHIPS ‐ morph We can allow more than one model to relate with our model. Many applications
  71. 71. Example Database schema users id ‐ integer name ‐ string groups id ‐ integer name ‐ string pictures id ‐ integer path‐ string owner_id ‐ integer owner_type ‐ string RELATIONSHIPS ‐ morph
  72. 72. RELATIONSHIPS ‐ notes Dynamic properties $post‐>comments; //get all comments as a collection $post‐>comments(); //returns a relationship class // Can be used as query builders $post‐>comments()‐>where('like', '>', 5);
  73. 73. RELATIONSHIPS ‐ notes Check if it exists Post::has('comments', '>=', 3)‐>get(); Post::doesntHave('comments')‐>get();
  74. 74. RELATIONSHIPS ‐ notes Eager Loading // Instead of this $users = AppUser::all(); foreach ($users as $user) { echo $user‐>contact‐>phone; } // We do this $user = AppUser::with('contact')‐>get();
  75. 75. Inserting & Updating create﴾﴿ save﴾﴿ associate﴾﴿ dissociate﴾﴿ attach﴾﴿ detach﴾﴿ sync﴾﴿ toggle﴾﴿ RELATIONSHIPS ‐ notes We have many ways to modify relationships
  76. 76. RELATIONSHIPS ‐ notes So many more lovely capabilities. https://laravel.com/docs/5.4/ eloquent‐relationships
  77. 77. QUESTIONS? Twitter: @StephenAfamO GitHub: @StephenAfamO Website: https://stephenafamo.com
  78. 78. THANK YOU Twitter: @StephenAfamO GitHub: @StephenAfamO Website: https://stephenafamo.com

×