{"id":4783,"date":"2024-09-14T07:07:46","date_gmt":"2024-09-14T07:07:46","guid":{"rendered":"https:\/\/rengga.dev\/blog\/?p=4783"},"modified":"2024-09-14T07:08:35","modified_gmt":"2024-09-14T07:08:35","slug":"starting-a-new-laravel-app-with-the-shouldbestrict-model","status":"publish","type":"post","link":"https:\/\/rengga.dev\/blog\/starting-a-new-laravel-app-with-the-shouldbestrict-model\/","title":{"rendered":"Starting a New Laravel App with the shouldBeStrict Model"},"content":{"rendered":"<p><strong>Rengga Dev<\/strong> &#8211; So you have an idea for a brand new app. You install Laravel, you&#8217;re ready to get started. What&#8217;s the first thing you should do?<\/p>\n<p>For me, I open up the app service provider and go down to the boot method and set the global\u00a0<code>Model::shouldBeStrict()<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">public function boot(): void\r\n{\r\n    Model::shouldBeStrict();\r\n}<\/pre>\n<p>With this turned on it does the following:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">public static function shouldBeStrict(bool $shouldBeStrict = true)\r\n{\r\n    static::preventLazyLoading($shouldBeStrict);\r\n    static::preventSilentlyDiscardingAttributes($shouldBeStrict);\r\n    static::preventAccessingMissingAttributes($shouldBeStrict);\r\n}\r\n<\/pre>\n<p>This does three things:<\/p>\n<ol>\n<li>Prevents lazy loading<\/li>\n<li>It prevents silently discarding attributes.<\/li>\n<li>It prevents accessing missing attributes.<\/li>\n<\/ol>\n<h2>Preventing Lazy Loading<\/h2>\n<p>Here is an example of lazy loading.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">$articles = \\App\\Models\\Article::get();\r\n \r\nforeach ($articles as $article) {\r\n     echo \"&lt;li&gt;\" . $article-&gt;user-&gt;name . \"&lt;\/li&gt;\\n\";\r\n}<\/pre>\n<p>If you run this, it will output what you expect. However, it\u2019s lazy loading the user relationship, causing a new query for every loop.<\/p>\n<p>With\u00a0<code>shouldBeStrict<\/code>\u00a0turned on instead of running the code you\u2019ll get an error giving you instant feedback:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">Attempted to lazy load [user] on model [App\\Models\\Article] but lazy loading is disabled.<\/pre>\n<h2>Prevent Silently Discarding Attributes<\/h2>\n<p>Here is an example showing trying to update an attribute that is not fillable:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">$user-&gt;fill([\"remember_token\" =&gt; \"bar\"]);\r\n<\/pre>\n<p>Now this will return an exception:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">Add fillable property [remember_token] to allow mass assignment on [App\\Models\\User].<\/pre>\n<h2>Prevent Accessing Missing Attributes.<\/h2>\n<p>Let\u2019s pretend we are trying to display a property on the User that may not exist:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">{{ $user-&gt;nonexistant }}<\/pre>\n<p>By default, Laravel will just not display anything because the property is not found, but with Strict mode turned on you get:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">The attribute [nonexistant] either does not exist or was not retrieved for model [App\\Models\\User].<\/pre>\n<p>This really helps in cases where you might make a spelling mistake like:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">{{ $user-&gt;emial }}<\/pre>\n<p>Now, you\u2019ll get instant feedback you messed up.<\/p>\n<p>Turning on\u00a0<code>Model::shouldBeStrict()<\/code>\u00a0is now the first thing I do on every app, and it helps prevent me from making basic mistakes that could be harmful to the app later on.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Rengga Dev &#8211; So you have an idea for a brand new <a class=\"read-more\" href=\"https:\/\/rengga.dev\/blog\/starting-a-new-laravel-app-with-the-shouldbestrict-model\/\" title=\"Starting a New Laravel App with the shouldBeStrict Model\" itemprop=\"url\"><\/a><\/p>\n","protected":false},"author":1,"featured_media":4784,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[708,676,727],"newstopic":[597,574],"class_list":{"0":"post-4783","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-web-development","8":"tag-laravel","9":"tag-rengga-dev","10":"tag-shouldbestrict","11":"newstopic-laravel","12":"newstopic-php"},"_links":{"self":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/4783","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/comments?post=4783"}],"version-history":[{"count":1,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/4783\/revisions"}],"predecessor-version":[{"id":4785,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/4783\/revisions\/4785"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media\/4784"}],"wp:attachment":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media?parent=4783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/categories?post=4783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/tags?post=4783"},{"taxonomy":"newstopic","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/newstopic?post=4783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}