<?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: hasanmn</title>
    <description>The latest articles on DEV Community by hasanmn (@hasanmn).</description>
    <link>https://dev.to/hasanmn</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%2F100290%2F3fe197b5-1e3a-4cc8-b290-b6cc088eeba5.png</url>
      <title>DEV Community: hasanmn</title>
      <link>https://dev.to/hasanmn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hasanmn"/>
    <language>en</language>
    <item>
      <title>Using Gemini CLI with Vertex AI (Without Worrying About Your Data)</title>
      <dc:creator>hasanmn</dc:creator>
      <pubDate>Fri, 17 Apr 2026 22:24:28 +0000</pubDate>
      <link>https://dev.to/hasanmn/using-gemini-cli-with-vertex-ai-without-worrying-about-your-data-4jb</link>
      <guid>https://dev.to/hasanmn/using-gemini-cli-with-vertex-ai-without-worrying-about-your-data-4jb</guid>
      <description>&lt;p&gt;If you've been playing around with Gemini CLI, you might have glossed over a small but important detail: when you use it through the standard Gemini API, there's a real chance your input data gets fed back into Google's model training pipeline. For personal tinkering, that's probably fine. For anything work-related -- internal tools, client data, proprietary code -- that's a different story.&lt;/p&gt;

&lt;p&gt;The fix is straightforward: route everything through &lt;strong&gt;Vertex AI&lt;/strong&gt; instead. Google's enterprise data handling guarantees apply there, which means your prompts stay your prompts. This post walks through the full setup from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;You'll need Node.js installed on your machine. That's it on the local side. On the cloud side, you'll need a GCP project with billing enabled and the &lt;code&gt;gcloud&lt;/code&gt; CLI installed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 -- Install Gemini CLI
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @google/gemini-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A global install so you can call &lt;code&gt;gemini&lt;/code&gt; from anywhere in your terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 -- Configure GCP
&lt;/h2&gt;

&lt;p&gt;Two things to do in the GCP console:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable the Vertex AI API&lt;/strong&gt; for your project. Navigate to &lt;em&gt;APIs &amp;amp; Services → Library&lt;/em&gt;, search for "Vertex AI API", and hit Enable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a service account&lt;/strong&gt; for the CLI to impersonate:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create the service account
gcloud iam service-accounts create svc-vertex-cli \
  --display-name="Gemini CLI Service Account"

# Grant the minimum required role
gcloud projects add-iam-policy-binding &amp;lt;PROJECT_ID&amp;gt; \
  --member="serviceAccount:svc-vertex-cli@&amp;lt;PROJECT_ID&amp;gt;.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;roles/aiplatform.user&lt;/code&gt; role is the minimum needed to execute prompts. If your organization enforces keyless authentication (a smart policy worth enabling), you can ban service account key creation under Organization Policies -- the ADC approach in Step 4 doesn't need a key file anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 -- Set Up Environment Variables
&lt;/h2&gt;

&lt;p&gt;Gemini CLI loads environment variables from &lt;code&gt;~/.gemini/.env&lt;/code&gt;. Create it if it doesn't exist:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p ~/.gemini
vim ~/.gemini/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then add the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GOOGLE_GENAI_USE_VERTEXAI=true
GOOGLE_CLOUD_PROJECT=&amp;lt;PROJECT_ID&amp;gt;
GOOGLE_CLOUD_LOCATION=us-central1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A note on location: &lt;code&gt;us-central1&lt;/code&gt; is the safest default since it has the broadest model availability. Other regions may not support all models yet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you have &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt; or &lt;code&gt;GEMINI_API_KEY&lt;/code&gt; set anywhere in your environment, you must unset them. They take precedence and will prevent ADC from working.&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unset GOOGLE_API_KEY
unset GEMINI_API_KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 4 -- Log In with ADC
&lt;/h2&gt;

&lt;p&gt;Application Default Credentials (ADC) is how the CLI authenticates without needing a service account key file sitting on disk. The trick is to log in as yourself first, then impersonate the service account:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Log in with your own Google account
gcloud auth login

# Create ADC credentials that impersonate the service account
gcloud auth application-default login \
  --impersonate-service-account=svc-vertex-cli@&amp;lt;PROJECT_ID&amp;gt;.iam.gserviceaccount.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The second command creates a credentials file that the CLI (and any other GCP SDK) picks up automatically. Your personal account needs the &lt;code&gt;roles/iam.serviceAccountTokenCreator&lt;/code&gt; role on the service account to impersonate it -- if you get a permission error, that's the likely cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 -- Run It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Interactive mode&lt;/strong&gt; -- starts a REPL-style session:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gemini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Single prompt&lt;/strong&gt; -- great for scripting or quick one-offs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gemini -p "Summarize this in 3 bullet points: ..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Specify a model&lt;/strong&gt; -- pass the model ID directly:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gemini -m gemini-2.5-pro&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Why Bother with All This?&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Fair question -- the standard Gemini API is easier to set up. The trade-off comes down to data control. Vertex AI gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No training data opt-in&lt;/strong&gt; -- your inputs aren't used to improve Google's models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise compliance&lt;/strong&gt; -- easier to satisfy security reviews and internal policies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit logging&lt;/strong&gt; -- Cloud Logging captures every API call, useful for debugging and compliance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyless auth&lt;/strong&gt; -- no credentials file to accidentally commit or rotate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a CLI tool you're going to use daily on real work, that's a worthwhile few extra minutes of setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemini&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start interactive mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemini -p "..."&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a single prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemini -m &amp;lt;model-id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specify a model&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Once it's running, the experience is identical to the regular Gemini CLI -- the Vertex AI routing is completely transparent. You get all the same features, just without the data handling concerns.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>gemini</category>
      <category>google</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Automatically Update `created_by` and `updated_by` in Laravel Using Bootable Traits</title>
      <dc:creator>hasanmn</dc:creator>
      <pubDate>Sun, 17 Oct 2021 01:43:41 +0000</pubDate>
      <link>https://dev.to/hasanmn/automatically-update-createdby-and-updatedby-in-laravel-using-bootable-traits-28g9</link>
      <guid>https://dev.to/hasanmn/automatically-update-createdby-and-updatedby-in-laravel-using-bootable-traits-28g9</guid>
      <description>&lt;p&gt;If you use &lt;code&gt;timestamps&lt;/code&gt; feature in Laravel, then you got the free feature of auto-update on &lt;code&gt;created_at&lt;/code&gt; and &lt;code&gt;update_at&lt;/code&gt; columns when the model is created or updated. Now, what if you want the same thing for you own customs &lt;code&gt;created_by&lt;/code&gt; and &lt;code&gt;updated_by&lt;/code&gt; columns? You want them to be automatically updated with the logged in user's &lt;code&gt;id&lt;/code&gt;. Well, you can use &lt;a href="https://laravel.com/docs/8.x/eloquent#observers"&gt;observer&lt;/a&gt; or hook into model's lifecycle in &lt;code&gt;boot&lt;/code&gt; or &lt;code&gt;booted&lt;/code&gt; methods of the model. Let's use example of &lt;code&gt;Post&lt;/code&gt; model as follows:&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="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Models&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;Illuminate\Database\Eloquent\Model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// updating created_by and updated_by when model is created&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;creating&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isDirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_by'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;created_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&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;user&lt;/span&gt;&lt;span class="p"&gt;()&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="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isDirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'updated_by'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;updated_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&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;user&lt;/span&gt;&lt;span class="p"&gt;()&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="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// updating updated_by when model is updated&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;updating&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isDirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'updated_by'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;updated_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&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;user&lt;/span&gt;&lt;span class="p"&gt;()&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="p"&gt;;&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we hook into &lt;code&gt;creating&lt;/code&gt; and &lt;code&gt;updating&lt;/code&gt; lifecycle of the &lt;code&gt;Post&lt;/code&gt; model. This works perfectly and is certainly convenient if you have only few models to apply this feature to. But what if you have many models? You have to apply the above code to all the models. Yes, it will work, but you know, it is not DRY. &lt;/p&gt;

&lt;p&gt;The bootable trait, which is also used by Laravel's &lt;a href="https://laravel.com/docs/8.x/eloquent#soft-deleting"&gt;SoftDeletes&lt;/a&gt; trait, can save you a ton in this situation. Laravel' Eloquent model will boot a trait's method with the name of pattern &lt;code&gt;boot[TraitName]&lt;/code&gt;. If you take a look into &lt;a href="https://github.com/laravel/framework/blob/8.x/src/Illuminate/Database/Eloquent/Model.php"&gt;Laravel's source code&lt;/a&gt;, you can find the snippet below.&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="cd"&gt;/**
     * Bootstrap the model and its traits.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bootTraits&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Boot all of the bootable traits on the model.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;bootTraits&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static&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="nv"&gt;$booted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;class_uses_recursive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$trait&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'boot'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class_basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$trait&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;in_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$booted&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nb"&gt;forward_static_call&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;$class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$method&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

                &lt;span class="nv"&gt;$booted&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$method&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code tells us the trait with the name of &lt;code&gt;boot[traitName]&lt;/code&gt; will also be invoked when the model is booted.&lt;/p&gt;

&lt;p&gt;Knowing this, we now can create a new trait called &lt;code&gt;CreatedUpdatedBy&lt;/code&gt; with a method of &lt;code&gt;bootCreatedUpdatedBy&lt;/code&gt; as follows.&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="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Traits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;trait&lt;/span&gt; &lt;span class="nc"&gt;CreatedUpdatedBy&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;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;bootCreatedUpdatedBy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// updating created_by and updated_by when model is created&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;creating&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isDirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_by'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;created_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&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;user&lt;/span&gt;&lt;span class="p"&gt;()&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="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isDirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'updated_by'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;updated_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&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;user&lt;/span&gt;&lt;span class="p"&gt;()&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="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// updating updated_by when model is updated&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;updating&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isDirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'updated_by'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;updated_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&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;user&lt;/span&gt;&lt;span class="p"&gt;()&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="p"&gt;;&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we can easily use it in any model that we want to apply it to just like when we use &lt;code&gt;SoftDeletes&lt;/code&gt; trait. For example in our &lt;code&gt;Post&lt;/code&gt; method, it should be looked 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="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Models&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;App\Traits\CreatedUpdatedBy&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;Illuminate\Database\Eloquent\Model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&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;CreatedUpdatedBy&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;Whenever the &lt;code&gt;Post&lt;/code&gt; model is created or updated, the &lt;code&gt;created_by&lt;/code&gt; and/or &lt;code&gt;updated_by&lt;/code&gt; will be automatically updated. Cool! Isn't it? 😎 &lt;/p&gt;

&lt;p&gt;Note that the above is just one example of using bootable traits in the Eloquent model to automatically update &lt;code&gt;created_by&lt;/code&gt; and &lt;code&gt;updated_by&lt;/code&gt;. However, there are many applications of it. For example, you can use it to automatically &lt;a href="https://tighten.co/blog/laravel-tip-bootable-model-traits/"&gt;delete related models&lt;/a&gt;, &lt;a href="https://andy-carter.com/blog/using-laravel-s-eloquent-traits"&gt;update slugs&lt;/a&gt;, and many others you can think of.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>eloquent</category>
      <category>php</category>
      <category>trait</category>
    </item>
    <item>
      <title>How to Create Your Own Snippets in VS Code</title>
      <dc:creator>hasanmn</dc:creator>
      <pubDate>Sun, 30 May 2021 01:50:06 +0000</pubDate>
      <link>https://dev.to/hasanmn/how-to-create-your-own-snippets-in-vs-code-1h0c</link>
      <guid>https://dev.to/hasanmn/how-to-create-your-own-snippets-in-vs-code-1h0c</guid>
      <description>&lt;p&gt;I am always looking for a new way to improve my workflow, to be more efficient. I found that using snippets is one of many things that surely can enhance my productivity. With snippets, using only several characters you get a chunk of codes that you often use. Certainly, there are a lot of snippet extensions in the VS Code marketplace. These snippets are super awesome, offering you a huge number of snippets; any snippet that you can imagine probably exists there. But, to be honest, I only use a few of them, and I have a hard time remembering their prefixes. I feel that it is better to create my own snippet that suits my own workflow, and hence I can remember easily.&lt;/p&gt;

&lt;p&gt;Here is how I create my own snippets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install  &lt;a href="https://marketplace.visualstudio.com/items?itemName=wware.snippet-creator"&gt;Snippet Creator Extension&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the editor, type a block of codes that you want to use as the snippet. Highlight them, open the command palette ( use &lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;shift&lt;/code&gt; + &lt;code&gt;p&lt;/code&gt;), select &lt;code&gt;Create Snippet&lt;/code&gt;,  and if you follow the suggested options, you will be fine. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IyyoJ-JZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7f740gyztndx48b6w5w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IyyoJ-JZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7f740gyztndx48b6w5w.gif" alt="Create Snippet"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the created snippet to further accommodate your needs. Open command palette and select &lt;code&gt;Preference: Configure User Snippets&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CsBWuEUx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kdi764oax2rp42uvgm2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CsBWuEUx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kdi764oax2rp42uvgm2.gif" alt="Modify Snippet"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now you can enjoy it. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fKBVIOpF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydt2i7leg70sk3uoge3l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fKBVIOpF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydt2i7leg70sk3uoge3l.gif" alt="Use Snippet"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>snippet</category>
      <category>extensions</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
