<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: bakle</title>
    <description>The latest articles on DEV Community by bakle (@bakle).</description>
    <link>https://dev.to/bakle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F227798%2Fd95aa3e3-f391-4d85-982a-5f20d68cb275.jpg</url>
      <title>DEV Community: bakle</title>
      <link>https://dev.to/bakle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bakle"/>
    <language>en</language>
    <item>
      <title>The Factory Method Pattern</title>
      <dc:creator>bakle</dc:creator>
      <pubDate>Mon, 24 Jan 2022 12:09:17 +0000</pubDate>
      <link>https://dev.to/bakle/the-factory-method-pattern-1a1f</link>
      <guid>https://dev.to/bakle/the-factory-method-pattern-1a1f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method let a class defer instantiation to subclasses.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When talking about factory method, we talk about a pattern that solves a common problem in software development (that’s why it’s a design pattern). That problem it’s called &lt;strong&gt;class dependency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Of course it solves other problems and in this article I’m going to mention some of them.&lt;/p&gt;

&lt;p&gt;So, according to the definition, we need to define an interface (remember that when we talk about interface is not necessary an “interface” type, it could be an abstract class or any super class). But what does the interface need to have? What methods we have to define? Also, does it need properties?&lt;/p&gt;

&lt;p&gt;Well, the answer is simple, we need the &lt;strong&gt;Factory Method&lt;/strong&gt;. Be careful that when we say that the interface needs the factory method it doesn’t mean that is the only method the interface can have. The &lt;strong&gt;Factory Method&lt;/strong&gt; is the method that have all the logic to create an object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the class diagram
&lt;/h2&gt;

&lt;p&gt;Let’s begin by creating the part where it say “&lt;em&gt;Defines an interface for creating an object, but lets subclasses decid which class to instantiate.&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j714rB6J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdwg37pysruia5neipis.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j714rB6J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdwg37pysruia5neipis.png" alt="Image description" width="880" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty simple, right?&lt;/p&gt;

&lt;p&gt;Now we have to complete the second part of the diagram. For this, we need to think that the subclass is in charge of creating the objects, and because this class decides which object is going to create, the only way to return the same type of an object is by creating another interface for this object.&lt;/p&gt;

&lt;p&gt;What I mean with this is that if we have a &lt;strong&gt;ConcreteFactoryClass&lt;/strong&gt; this class can instantiate different concrete classes. For example we can have a &lt;strong&gt;DatabaseFactory&lt;/strong&gt;, and this factory can return an instance of MySQL, MongoDB, PostgreSQL, etc. This is not right because this factory needs to return a type that is common for every Database classes, and that is why every concrete database needs to implement an interface.&lt;/p&gt;

&lt;p&gt;So, with this definition, the &lt;strong&gt;Factory Method Pattern&lt;/strong&gt; class diagram looks like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EEGHw8H2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28ybkz6arz791vxphf7t.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EEGHw8H2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28ybkz6arz791vxphf7t.jpeg" alt="Class Diagram" width="880" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying The Factory Method Pattern
&lt;/h2&gt;

&lt;p&gt;Let’s imagine that we need to create multiple database classes like MySQL, PostgreSQL and MongoDB. They are simple classes that have some methods like “select”, “insert”, “update” and “delete”.&lt;/p&gt;

&lt;p&gt;Each class know the syntax to execute each statement.&lt;/p&gt;

&lt;p&gt;Our class diagram looks like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2wjSMt2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1n3su97vxto7qk4h90o7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2wjSMt2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1n3su97vxto7qk4h90o7.jpeg" alt="Concrete Factory Method Pattern" width="880" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the &lt;strong&gt;create&lt;/strong&gt; method in the factory is our &lt;strong&gt;FactoryMethod&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions you may ask
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why do we need a FactoryInterface if there is only one ConcreteFactory?
&lt;/h3&gt;

&lt;p&gt;Each case is different, we provide an interface because we need to make sure that the ConcreteFactory have this method. In some cases is possible you could have many ConcreteFactories (maybe a company and its branch offices).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this pattern solve class dependencies?
&lt;/h3&gt;

&lt;p&gt;Imagine if we have in the main class (where we use the factory) a lot of if statements asking if the type is “mysql” or “postgresql”, etc. For each specific case it instantiate the concrete class. Thus, the main class will depend on every concrete DB class. Applying the factory method, the main class will depend on the &lt;strong&gt;DB&lt;/strong&gt; abstract class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can this pattern solve an Open-Close principle violation?
&lt;/h3&gt;

&lt;p&gt;Of course, let's the take the example of the previous question (the one where we have many if statements). So every time we need to add a new concrete DB class we have to change the code of our main class. By applying the &lt;strong&gt;factory method&lt;/strong&gt;, any new concrete class will be added in our factory not in the main class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code implementation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/bakle/Design-Patterns/tree/main/src/FactoryMethodPattern"&gt;Factory Method Pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Follow me on:&lt;/strong&gt; &lt;a href="https://twitter.com/Bashir_Akle"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Observer Pattern</title>
      <dc:creator>bakle</dc:creator>
      <pubDate>Sat, 30 Oct 2021 15:51:10 +0000</pubDate>
      <link>https://dev.to/bakle/the-observer-pattern-3pe4</link>
      <guid>https://dev.to/bakle/the-observer-pattern-3pe4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Observer Pattern defines a one-to-many dependency between objects, so that when one object change state, all of its depedents are notified and updated automatically.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we talk about the observer pattern you can think of a newspaper and its subscribers, or an application that has to send notifications to their users. In both examples we can define each actor as &lt;strong&gt;subject&lt;/strong&gt;(i.e: newspaper) and &lt;strong&gt;observers&lt;/strong&gt;(i.e: subscribers).&lt;/p&gt;

&lt;p&gt;Let's take for example an e-commerce platform, so when a user makes a purchase they receive a notification about the order. For example, I can go to my settings and check the checkboxes to receive a notification via Email, SMS and Phone Call. So, when I make a purchase, an order is created and then I receive a notification for each channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlynrkphzzec1fp8fssq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlynrkphzzec1fp8fssq.jpeg" alt="One-to-many Relationship"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we see the image above, we can see that the relationship between the &lt;strong&gt;subject&lt;/strong&gt; and the &lt;strong&gt;observers&lt;/strong&gt; is the &lt;strong&gt;one-to-many&lt;/strong&gt; relationship that we defined earlier.&lt;/p&gt;

&lt;p&gt;The subject is the object that contains the &lt;strong&gt;state&lt;/strong&gt;, and the observers use that state, so when the data changes in the subject (the order) the observers are updated.&lt;/p&gt;

&lt;p&gt;Now that we understand the definition of the Observer Pattern we can take a look at the class diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qig55ilt7ufqmtficp1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qig55ilt7ufqmtficp1.png" alt="Class diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explaining the class diagram
&lt;/h2&gt;

&lt;p&gt;The Observer pattern class diagram tell us that we need to have two &lt;strong&gt;interfaces&lt;/strong&gt; (when we say &lt;strong&gt;interface&lt;/strong&gt; we are referring to a contract, not a specific interface type, we can define either an abstract class or an interface type). One interface defines the methods that any subject needs to implement, and the other interface defines the methods that observers need to implement. &lt;/p&gt;

&lt;p&gt;Also, the Subject interface Has-A (Filled arrow) observer interface. This means that the subject needs to have the observers list.&lt;/p&gt;

&lt;p&gt;Finally, we have our concrete classes that implements our interfaces, so we have the &lt;strong&gt;ConcreteSubject&lt;/strong&gt; and the &lt;strong&gt;ConcreteObserver&lt;/strong&gt; (There could be many &lt;strong&gt;ConcreteObserver&lt;/strong&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying the class diagram
&lt;/h2&gt;

&lt;p&gt;So, in the case of our example of the order and the notification channels we can have the following class diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftdu8jvkik06lr4148i9c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftdu8jvkik06lr4148i9c.png" alt="Concrete observer pattern"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of this pattern
&lt;/h2&gt;

&lt;p&gt;The Observer pattern provides an object design where subjects and observers are loosely coupled. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Because subject doesn’t depend on concrete classes but interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The only thing subject knows about an  observer is that it implements an interface (The observer interface).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We don’t need to modify the subject to add new types of observers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Variations
&lt;/h2&gt;

&lt;p&gt;This pattern can have some variations, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The way we register the observers (each observer could register themself via constructor or we could have an array to register all observers to the subject).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The way we get the data from the subject (subject can push the data to the observer or the observer can pull the data from the subject).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In conclusion, the whole idea of this pattern is to communicate a state to a group of objects in a loosely coupled way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code implementation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/bakle/Design-Patterns/tree/main/src/ObserverPattern" rel="noopener noreferrer"&gt;Observer Pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Follow me on:&lt;/strong&gt; &lt;a href="https://twitter.com/Bashir_Akle" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>design</category>
      <category>php</category>
      <category>oop</category>
    </item>
    <item>
      <title>Laravel URL Presenters</title>
      <dc:creator>bakle</dc:creator>
      <pubDate>Tue, 08 Jun 2021 02:05:01 +0000</pubDate>
      <link>https://dev.to/bakle/laravel-url-presenters-4f2e</link>
      <guid>https://dev.to/bakle/laravel-url-presenters-4f2e</guid>
      <description>&lt;p&gt;Usually, we always find new ways to make our backend code cleaner, readable and flexible by applying design patters, software principles, refactoring strategies, etc.&lt;/p&gt;

&lt;p&gt;This time, the strategy we are going to apply is about communication of backend and frontend and how the backend code can provide much more information to our views.&lt;/p&gt;

&lt;p&gt;Most of us render the application routes directly in the view, and sometimes we find that we are repeating these same routes along the view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_kDvD1Lb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xavn7oslq887lcpoc90d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_kDvD1Lb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xavn7oslq887lcpoc90d.png" alt="Index view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that we are repeating the same url in lines #19 and #28. This is the good way, some people use (see line #2):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wsd1ZhS_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0etz3vz6pui3386n7oz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wsd1ZhS_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0etz3vz6pui3386n7oz.png" alt="Index view 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, how can we make this a little bit cleaner and reusable along the application? Well, we can apply a Url Presenter.&lt;/p&gt;

&lt;p&gt;There are many ways to do it, so I'm going to show you one of them. &lt;/p&gt;

&lt;p&gt;Some people like to do it inside the model, which I think is not the best way because we are giving a responsibility to the model that should not have, I mean, why the model should know about urls?&lt;/p&gt;

&lt;p&gt;Let's begin with the first step.&lt;br&gt;
 &lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Creating an interface
&lt;/h3&gt;

&lt;p&gt;When I talk about interface I mean that it could be an abstract class or interface, that depends on your need. This time we are going to make a simple interface for a url resource (index, show, edit, ...).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hHXIMp5S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t16pn1rngnwpw0r0hd9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hHXIMp5S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t16pn1rngnwpw0r0hd9g.png" alt="Interface"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Creating concrete url presenter
&lt;/h3&gt;

&lt;p&gt;Now, we just create a concrete url presenter, in this case we are going to create a &lt;code&gt;UserUrlPresenter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N0_NF6i5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ld078vxbnc1nyeja46lb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N0_NF6i5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ld078vxbnc1nyeja46lb.png" alt="Concrete"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Using the presenter
&lt;/h3&gt;

&lt;p&gt;Let's suppose we have our UserController, we just have to pass the url presenter to the view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZepPcP9O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2ktmhftzi4l9gmhcgmt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZepPcP9O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2ktmhftzi4l9gmhcgmt.png" alt="Controller"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Final view
&lt;/h3&gt;

&lt;p&gt;Now, we can use the url presenter inside the view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uCtr3XjH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weo9t3lgvo3kwmqn6lua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uCtr3XjH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weo9t3lgvo3kwmqn6lua.png" alt="Final View"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;br&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;p&gt;I know I said that I am not a fan of url presenters inside the model, but I will give you an example of how to do it.&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the interface
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RoT1xoDr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uu81x51nib8jmii26gi7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RoT1xoDr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uu81x51nib8jmii26gi7.png" alt="Interface"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Creating concrete url presenter
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jhci87vg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cpp0kn78ggrlxujd47sc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jhci87vg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cpp0kn78ggrlxujd47sc.png" alt="Concrete presenter url 2"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  The presenter in the model
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sXKLif7U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7os4ssznfcggzybc7nr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sXKLif7U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7os4ssznfcggzybc7nr.png" alt="Model"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Using the presenter
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XdsqRH6G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7enmoox8wvavjja39xf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XdsqRH6G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7enmoox8wvavjja39xf.png" alt="Controller 2"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Final View
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uK1_-Sk4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brck81eyfix3fmy19fzr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uK1_-Sk4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brck81eyfix3fmy19fzr.png" alt="Index 3"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Laravel fit models.</title>
      <dc:creator>bakle</dc:creator>
      <pubDate>Sat, 03 Oct 2020 14:32:51 +0000</pubDate>
      <link>https://dev.to/bakle/laravel-fit-models-1ca6</link>
      <guid>https://dev.to/bakle/laravel-fit-models-1ca6</guid>
      <description>&lt;p&gt;Time ago in the Laravel community, people were talking about how to balance responsibilities between models and controllers. Some people say that it was better making fat models and thin controllers, while others say the opposite. This time I'm going to talk about a strategy to reduce a model when it becomes too "fat".&lt;/p&gt;

&lt;p&gt;The concept of "fit models" came up from the need of reducing the amount of methods within a model. Months ago I was looking and thinking for a better way to reduce the amount of methods in a "fat" model and I came up with a solution, and searching for some articles I didn't found anyone who applied this, until I recently found that Freek Van Der Herten tried this same approach.&lt;/p&gt;

&lt;p&gt;In a medium-large scale application is normal to have lots of methods for relationships, accessors, mutators and more.&lt;/p&gt;

&lt;p&gt;Let's look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Authenticatable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasFactory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Notifiable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that are mass assignable.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'remember_token'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that should be cast to native types.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$casts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'email_verified_at'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'datetime'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'birth_date'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'datetime'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Follower&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;favorites&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Favorite&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;socialNetworks&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SocialNetwork&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;phones&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Phone&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getFullNameAttribute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getShortNameAttribute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getAgeAttribute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;diffInYears&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;birth_date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getCreatedDateAttribute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFormattedDateString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getProfilePicturePathAttribute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;storage_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'pictures/'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;profile_picture&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFirstNameAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$firstName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'first_name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;studly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$firstName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setLastNameAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'last_name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;studly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lastName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;User&lt;/code&gt; model has some relationships, accessors and mutators, also remember that methods could increase a lot. At this time we can see too many things in our code and it is hard to read despite it's not a "fat" model. &lt;/p&gt;

&lt;p&gt;Moreover, in a collaborative project developers try to define how to organize those methods. In the previous code we saw that relationships were first, then accessors and then mutators. When new relationships or accessors come in, developers will try to keep that structure, but when the team is growing new developers will add new methods wherever they want, making this previous structure a mess.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traits to the rescue
&lt;/h3&gt;

&lt;p&gt;So, what are traits? In simple words, they are a way to reuse code and reduce limitations of single inheritance. Although, a trait is something that can't be inheritable and is more like an extension of a class.&lt;/p&gt;

&lt;p&gt;What if we separate each type of methods and put them in a trait? This way we can create a specific trait for each one. For example, we can create a &lt;code&gt;HasUserAccessors&lt;/code&gt; for keeping all user's accessors and a &lt;code&gt;HasUserMutators&lt;/code&gt; for keeping all user's mutators.&lt;/p&gt;

&lt;p&gt;With this approach our &lt;code&gt;User&lt;/code&gt; model will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Authenticatable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasFactory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Notifiable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasUserAccessors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasUserMutators&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that are mass assignable.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'remember_token'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that should be cast to native types.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$casts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'email_verified_at'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'datetime'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'birth_date'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'datetime'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Follower&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;favorites&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Favorite&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;socialNetworks&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SocialNetwork&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;phones&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Phone&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;HasMany&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better?&lt;/p&gt;

&lt;p&gt;In fact, we can go further by creating a &lt;code&gt;HasUserRelationships&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Authenticatable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasFactory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Notifiable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasUserAccessors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasUserMutators&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasUserRelationships&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that are mass assignable.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'remember_token'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The attributes that should be cast to native types.
     *
     * @var array
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$casts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'email_verified_at'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'datetime'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'birth_date'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'datetime'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I know that some of you will say that is not a valid approach because we are not reusing a trait and it goes against the definition of trait, but remember that just because something can be reused doesn't mean that you have to. For example, classes can be extended but do you extend every class? Of course not, you create them for specific purposes with no need to apply inheritance.&lt;/p&gt;

&lt;p&gt;Remember when I said that traits are not inheritable? It is because you cannot have a class that extends a trait, also you can't hide a trait's properties. If you have a private property inside a trait, when you use that trait in a class that class will own the property, it is like creating the property directly inside the class.&lt;/p&gt;

&lt;p&gt;This is why I think using traits to reduce models is totally valid because is like creating methods inside the model but making the model looks fit.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
    </item>
    <item>
      <title>Laravel assertions: The difference between asserts.</title>
      <dc:creator>bakle</dc:creator>
      <pubDate>Sun, 16 Feb 2020 22:09:12 +0000</pubDate>
      <link>https://dev.to/bakle/laravel-assertions-the-difference-between-asserts-8k1</link>
      <guid>https://dev.to/bakle/laravel-assertions-the-difference-between-asserts-8k1</guid>
      <description>&lt;h2&gt;
  
  
  Laravel assertions: The difference between asserts.
&lt;/h2&gt;

&lt;p&gt;I'm sure that most of us have had the doubt of which assertion to use when we are testing our application.&lt;br&gt;
Many times we use them without knowing how they really work.&lt;/p&gt;

&lt;p&gt;It's true that some of them are confusing, but each one has it own purpose, even though they are similar.&lt;/p&gt;

&lt;p&gt;Let's see some of them.&lt;/p&gt;
&lt;h3&gt;
  
  
  assertOk() Vs assertSuccessful()
&lt;/h3&gt;

&lt;p&gt;Let's see what &lt;code&gt;assertOk()&lt;/code&gt; does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;assertOk&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;PHPUnit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isOk&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'Response status code ['&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getStatusCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;'] does not match expected 200 status code.'&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;isOk&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, this assertion show us that the response status code must be excatly &lt;em&gt;200&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This assertion is useful for cases when we want to check exactly this status &lt;em&gt;200&lt;/em&gt;. For example, when we make a &lt;em&gt;get()&lt;/em&gt; request.&lt;/p&gt;

&lt;p&gt;Now, let's see what &lt;code&gt;assertSuccessful()&lt;/code&gt; does.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;assertSuccessful&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;PHPUnit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isSuccessful&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'Response status code ['&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getStatusCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;'] is not a successful status code.'&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;isSuccessful&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This assertion is not precisely to verify a &lt;em&gt;200&lt;/em&gt; status response code.&lt;br&gt;
If we use this to check an HTTP response and the response code is &lt;em&gt;200&lt;/em&gt;, it will pass.&lt;br&gt;
But, what would happen if the response is 201 (Created) or 204 (No content)?&lt;br&gt;
Do we want this response code or we really want a 200?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status"&gt;Check HTTP Response Status codes here.&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  assertSee() Vs assertSeeText()
&lt;/h3&gt;

&lt;p&gt;Let's see what &lt;code&gt;assertSee()&lt;/code&gt; does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;assertSee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;PHPUnit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertStringContainsString&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getContent&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, what this assertion does, is getting the content of the response and then checks if the value we are passing is within the content.&lt;/p&gt;

&lt;p&gt;For example, if we want to check if the content has "My App" in somewhere, we do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertSee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'My App'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what if the content is wrapped inside a span tag like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;My &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'text-blue'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;App&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The assertion we did before will fail. But why?&lt;/p&gt;

&lt;p&gt;Because in the content we have &lt;code&gt;My &amp;lt;span class='text-blue'&amp;gt;App&amp;lt;/span&amp;gt;&lt;/code&gt; and we are looking for &lt;code&gt;My App&lt;/code&gt; without anything else around.&lt;/p&gt;

&lt;p&gt;So, this assertion is helpful when we want to check a whole HTML tag too, for example, if we want&lt;br&gt;
to check that in the content we have a link to Google and the link text is "Google", we could do this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertSee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;a href="https://www.google.com/"&amp;gt;Google&amp;lt;/a&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;br&gt;&lt;br&gt;
Now, let's see what &lt;code&gt;assertSeeText()&lt;/code&gt; does.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;assertSeeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;PHPUnit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertStringContainsString&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;strip_tags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getContent&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can you see the difference?&lt;/p&gt;

&lt;p&gt;Yes, the only difference is the &lt;code&gt;strip_tags()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;This function removes all HTML and PHP tags in the content, so in the previous example (&lt;code&gt;My &amp;lt;span class='text-blue'&amp;gt;App&amp;lt;/span&amp;gt;&lt;/code&gt;), the &lt;code&gt;strip_tags()&lt;/code&gt; will remove the &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; tag and the content will be &lt;code&gt;My App&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, what will happen if we have &lt;code&gt;My &amp;lt;span class='text-blue'&amp;gt;App&amp;lt;/span&amp;gt;&lt;/code&gt; and we do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertSeeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'My App'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will work, because all HTML and PHP tags will be removed before it checks if the string is within the content.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
