<?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: Ernane Ferreira</title>
    <description>The latest articles on DEV Community by Ernane Ferreira (@ernanej).</description>
    <link>https://dev.to/ernanej</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%2F826332%2F5c1115ff-9dd8-4152-a5bf-9410178823b9.png</url>
      <title>DEV Community: Ernane Ferreira</title>
      <link>https://dev.to/ernanej</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ernanej"/>
    <language>en</language>
    <item>
      <title>Text Improvement Automation with AppleScript &amp; Gemini API 🔧</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Fri, 13 Sep 2024 20:06:58 +0000</pubDate>
      <link>https://dev.to/ernanej/text-improvement-automation-with-applescript-gemini-api-84f</link>
      <guid>https://dev.to/ernanej/text-improvement-automation-with-applescript-gemini-api-84f</guid>
      <description>&lt;p&gt;I'm currently experimenting with improving my texts using AI tools and it seems to have already become a common practice. Whether it was to correct spelling or refine the tone of my writing, I found myself repeatedly jumping to these AI platforms. It was efficient, but it felt a little tiring to do it every time.&lt;/p&gt;

&lt;p&gt;So, I decided to streamline this process and make it a bit more personal and integrated. Instead of going to an external site each time I needed text improvements, I thought, "Why not create an automation that does this on my system?"&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concept
&lt;/h2&gt;

&lt;p&gt;With the Gemini language model API from Google, I had a powerful tool at my disposal. I created a macOS automation using AppleScript to tap into this API and integrate it directly into my workflow. Here’s how I did it:&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ How to Set Up Your Own Text Improvement Automation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create the Automation with Automator
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open Automator&lt;/strong&gt; on macOS.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;"Workflow"&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;"The workflow receives current:"&lt;/strong&gt; to &lt;strong&gt;"text"&lt;/strong&gt; and &lt;strong&gt;"in:"&lt;/strong&gt; to &lt;strong&gt;"any application"&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In the sidebar, under &lt;strong&gt;Library&lt;/strong&gt;, search for and drag the &lt;strong&gt;"Run AppleScript"&lt;/strong&gt; block into the workflow.&lt;/li&gt;
&lt;li&gt;Copy the AppleScript code from &lt;a href="https://github.com/ErnaneJ/itwg-apple-automator" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and paste it into the &lt;strong&gt;AppleScript&lt;/strong&gt; block in Automator or simply copy the code below.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight applescript"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nb"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;selectedText&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as &lt;/span&gt;&lt;span class="nc"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Aprimore a escrita, ortografia e formalidade do seguinte texto a seguir. Seu retorno deve ser SOMENTE o texto ajustado sem conteúdo antes ou depois.\n"&lt;/span&gt;&lt;span class="w"&gt;

     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;apiKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;YOUR-GEMINI-API-KEY-HERE&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;curlCommand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"curl -s 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key="&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;apiKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"' -H 'Content-Type: application/json' -X POST -d '{\"contents\": [{\"parts\": [{\"text\": \""&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;selectedText&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\"}]}]}' | /opt/homebrew/bin/jq .candidates[0].content.parts[0].text"&lt;/span&gt;&lt;span class="w"&gt;

     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;jsonResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;do shell script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;curlCommand&lt;/span&gt;&lt;span class="w"&gt;

     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;textResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;do shell script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;quoted form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;jsonResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;" | sed 's/^\\\"//; s/\\\"$//; s/\\\\n/\\n/g'"&lt;/span&gt;&lt;span class="w"&gt;

     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;creditMessage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"🛠️ Developed by https://github.com/ErnaneJ"&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;fullMessage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;textResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;creditMessage&lt;/span&gt;&lt;span class="w"&gt;

     &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dialogResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;display dialog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;fullMessage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;buttons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Copy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Close"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;button&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Close"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"🤖 Result - Gemini (1.5 flash)"&lt;/span&gt;&lt;span class="w"&gt;

     &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;button returned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dialogResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Copy"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nb"&gt;set the clipboard to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;textResponse&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nb"&gt;display&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;notification&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Text copied to clipboard"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Copy"&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt;

     &lt;/span&gt;&lt;span class="nb"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;textResponse&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;run&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Modify the code&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prompt&lt;/strong&gt;: Adjust the &lt;code&gt;prompt&lt;/code&gt; variable to specify how you want the AI to process the text (e.g., level of formality or specific instructions).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Key&lt;/strong&gt;: Replace &lt;code&gt;"&amp;lt;YOUR-GEMINI-API-KEY-HERE&amp;gt;"&lt;/code&gt; with your own Gemini API key (you can get one &lt;a href="https://aistudio.google.com/app/apikey" rel="noopener noreferrer"&gt;here&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Install Dependencies
&lt;/h3&gt;

&lt;p&gt;The script uses &lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;jq&lt;/code&gt; for making requests and processing responses. Install them via Homebrew:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;curl jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Set the &lt;code&gt;jq&lt;/code&gt; Path
&lt;/h3&gt;

&lt;p&gt;Find the path to the &lt;code&gt;jq&lt;/code&gt; binary with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;which jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the &lt;code&gt;jq&lt;/code&gt; path in the script if necessary. Homebrew usually installs it to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/opt/homebrew/bin/jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Save and Run the Automation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Save the automation with the name &lt;strong&gt;"Improve Text With Gemini"&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;To use it, select text in any application with text field, go to the &lt;strong&gt;"Services"&lt;/strong&gt; menu, and click &lt;strong&gt;"Improve Text With Gemini"&lt;/strong&gt; or whatever name you gave to the file.&lt;/li&gt;
&lt;li&gt;A popup will appear with the enhanced text, and you can copy it directly to your clipboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🔍 Example of the Popup
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  💡 Customization Tips
&lt;/h2&gt;

&lt;p&gt;You can customize the script’s behavior by adjusting the &lt;code&gt;prompt&lt;/code&gt; variable in the AppleScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight applescript"&gt;&lt;code&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"......."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And make sure to replace &lt;code&gt;&amp;lt;YOUR-GEMINI-API-KEY-HERE&amp;gt;&lt;/code&gt; with your actual API key.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Creating this automation was interesting because I had never done anything like this before. It simplified my writing process, saved time, and made everything a little more efficient. If you often use text enhancement tools, consider how you can integrate them into your workflow. Sometimes it's easier than you think!&lt;/p&gt;

&lt;p&gt;Do you use similar tools? Share your experiences in the comments below! Feel free to check out the &lt;a href="https://github.com/ErnaneJ/itwg-apple-automator" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; for more code details or suggestions for improvements. &lt;/p&gt;

&lt;p&gt;Happy automation! 🤖&lt;/p&gt;

</description>
      <category>applescript</category>
      <category>gemini</category>
      <category>macos</category>
    </item>
    <item>
      <title>Build a Simple TODO List with Shell Script 🐚</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Thu, 12 Sep 2024 13:26:56 +0000</pubDate>
      <link>https://dev.to/ernanej/build-a-simple-todo-list-with-shell-script-4619</link>
      <guid>https://dev.to/ernanej/build-a-simple-todo-list-with-shell-script-4619</guid>
      <description>&lt;p&gt;Managing tasks directly from the terminal can be a breeze with the power of shell scripting! In this post, I'll walk you through creating a simple yet functional TODO list using a few shell functions. We'll store tasks in a text file, add unique identifiers to each item, and provide commands for adding, removing, and clearing tasks.&lt;/p&gt;

&lt;p&gt;Let’s dive in! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites ⚙️
&lt;/h2&gt;

&lt;p&gt;You'll need a terminal using &lt;code&gt;bash&lt;/code&gt; or &lt;code&gt;zsh&lt;/code&gt;. The following functions can be added to your &lt;code&gt;~/.zshrc&lt;/code&gt; or &lt;code&gt;~/.bashrc&lt;/code&gt; file to make them available as commands in your terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Set Up Your Storage 🎲
&lt;/h2&gt;

&lt;p&gt;First, let’s create an environment variable that defines where your tasks will be stored. Add this line to your configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TODO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/todo.txt"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will store your task list in a file called &lt;code&gt;todo.txt&lt;/code&gt; located in your home directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Define Your Functions ✨
&lt;/h2&gt;

&lt;p&gt;Now let's add some shell functions to manage our TODO list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tla&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$TODO&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$*&lt;/span&gt; | &lt;span class="nb"&gt;md5sum&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 1-4&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; 👉🏼 &lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$TODO&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$TODO&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
tlr&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="s2"&gt;"/^&lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;/d"&lt;/span&gt; &lt;span class="nv"&gt;$TODO&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$TODO&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
tl&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$TODO&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
tlc&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; /dev/null &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$TODO&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s what each function does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tla&lt;/code&gt; (Todo List Add)&lt;/strong&gt;: Adds tasks to the list. It generates a 4-character md5 hash to serve as a unique identifier for each task. If no argument is passed, it displays the current task list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tlr&lt;/code&gt; (Todo List Remove)&lt;/strong&gt;: Removes tasks from the list by matching their md5 identifier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tl&lt;/code&gt; (Todo List)&lt;/strong&gt;: Simply displays the current list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tlc&lt;/code&gt; (Todo List Clear)&lt;/strong&gt;: Clears the entire task list, removing all entries at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end of each operation, the current state of your TODO list will be displayed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: See It in Action ☕️
&lt;/h2&gt;

&lt;p&gt;Here’s a quick demonstration of how these commands work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  ~ tl       
➜  ~ tla &lt;span class="nb"&gt;test &lt;/span&gt;0
&lt;span class="c"&gt;# 0e57 👉🏼 test 0&lt;/span&gt;
➜  ~ tla &lt;span class="nb"&gt;test &lt;/span&gt;1
&lt;span class="c"&gt;# 0e57 👉🏼 test 0&lt;/span&gt;
&lt;span class="c"&gt;# 2490 👉🏼 test 1&lt;/span&gt;
➜  ~ tla &lt;span class="nb"&gt;test &lt;/span&gt;2
&lt;span class="c"&gt;# 0e57 👉🏼 test 0&lt;/span&gt;
&lt;span class="c"&gt;# 2490 👉🏼 test 1&lt;/span&gt;
&lt;span class="c"&gt;# b0b3 👉🏼 test 2&lt;/span&gt;
➜  ~ tlr 2490
&lt;span class="c"&gt;# 0e57 👉🏼 test 0&lt;/span&gt;
&lt;span class="c"&gt;# b0b3 👉🏼 test 2&lt;/span&gt;
➜  ~ tl
&lt;span class="c"&gt;# 0e57 👉🏼 test 0&lt;/span&gt;
&lt;span class="c"&gt;# b0b3 👉🏼 test 2&lt;/span&gt;
➜  ~ tlc
➜  ~ tl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tla test 0&lt;/code&gt;&lt;/strong&gt;: Adds "test 0" to the list with an md5 identifier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tlr 2490&lt;/code&gt;&lt;/strong&gt;: Removes the task with the identifier &lt;code&gt;2490&lt;/code&gt; (in this case, "test 1").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tlc&lt;/code&gt;&lt;/strong&gt;: Clears the list.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion ✍️
&lt;/h2&gt;

&lt;p&gt;With just a few lines of shell script, you now have a functional TODO list right in your terminal. You can easily add, remove, or clear tasks with simple commands. This setup is lightweight and can be modified to fit your workflow.&lt;/p&gt;

&lt;p&gt;Feel free to extend these functions or add your own twists. Happy hacking! 🚀&lt;/p&gt;

</description>
      <category>shell</category>
      <category>bash</category>
      <category>linux</category>
      <category>todolist</category>
    </item>
    <item>
      <title>🚀 Edge Detection with Threads and MiniMagick in Ruby 🌄</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Thu, 12 Sep 2024 01:53:17 +0000</pubDate>
      <link>https://dev.to/ernanej/edge-and-relief-detection-in-images-with-minimagick-and-ruby-threads-15i2</link>
      <guid>https://dev.to/ernanej/edge-and-relief-detection-in-images-with-minimagick-and-ruby-threads-15i2</guid>
      <description>&lt;p&gt;Digital image processing is a fascinating field where computers are used to transform, enhance, and interpret images. It plays a crucial role in numerous applications, from medical imaging to computer vision and machine learning. One of the foundational techniques in this domain is &lt;strong&gt;edge detection&lt;/strong&gt; ✨— a method used to identify significant transitions in pixel intensities, enabling us to detect objects and boundaries within images.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Why Edge Detection Matters
&lt;/h3&gt;

&lt;p&gt;Edges are essentially where the most critical information of an image lies. They represent boundaries between different objects, colors, or textures, making them vital for tasks like segmentation and object recognition. Without edge detection, computers would struggle to differentiate between regions in an image.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔨 How Edge Detection Works
&lt;/h3&gt;

&lt;p&gt;Edge detection is primarily achieved through mathematical operations called &lt;strong&gt;convolutions&lt;/strong&gt;. By applying convolution filters, we can detect changes in pixel intensities in both the horizontal (

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
) and vertical (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;yy &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
) directions. The most commonly used filters for edge detection are the &lt;code&gt;Prewitt&lt;/code&gt;, &lt;code&gt;Sobel&lt;/code&gt;, and &lt;code&gt;Canny&lt;/code&gt; operators. In this project, we focus on using the &lt;code&gt;Prewitt&lt;/code&gt; operator to perform this task.&lt;/p&gt;

&lt;p&gt;Consider the following convolution matrices for detecting edges in both directions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gx = |-1  0  1|    Gy = |-1 -1 -1|
     |-1  0  1|        |  0  0  0|
     |-1  0  1|        |  1  1  1|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GxG_x &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt; detects horizontal changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GyG_y &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt; detects vertical changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By applying these matrices across the image, we extract valuable edge information for each pixel. The final edge map is generated by combining both directional components.&lt;/p&gt;

&lt;h3&gt;
  
  
  📋 Step-by-Step Process
&lt;/h3&gt;

&lt;p&gt;Let's walk through the basic algorithm to detect edges in a grayscale image of size 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;M×NM \times N &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;M&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize Matrices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create three matrices: &lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GxG_x &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;, &lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GyG_y &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;, and &lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GG &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;, each of size 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;M×NM \times N &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;M&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
. These will store the horizontal, vertical, and final edge information, respectively.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Convolution Operation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For each pixel, the gradient in the 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
-direction (&lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GxG_x &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;) and 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;yy &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
-direction (&lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GyG_y &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;) is calculated using the convolution matrices.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Combine Results:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finally, the gradient magnitudes are combined to form the final edge-detected image, &lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GG &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;For&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="no"&gt;For&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="no"&gt;Gx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&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="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&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="no"&gt;If&lt;/span&gt; &lt;span class="no"&gt;Gx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Gx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="no"&gt;If&lt;/span&gt; &lt;span class="no"&gt;Gx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Gx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;

&lt;span class="no"&gt;For&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="no"&gt;For&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="no"&gt;N&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="no"&gt;G&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Gx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;Gy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;If&lt;/span&gt; &lt;span class="no"&gt;G&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;G&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧵 Multi-Threaded Implementation in Ruby
&lt;/h3&gt;

&lt;p&gt;A key feature of this project is its use of &lt;strong&gt;multi-threading&lt;/strong&gt; to parallelize the edge detection process 🧑‍💻. Instead of processing the entire image in a single thread, the work is divided into two threads:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One thread calculates the horizontal edges using &lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GxG_x &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Another thread handles the vertical edges with &lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GyG_y &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach significantly speeds up the computation, especially for large images.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Main thread&lt;/strong&gt;: Reads the input image, initializes matrices, and spawns two threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread 1&lt;/strong&gt;: Computes the edge detection in the 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
-direction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread 2&lt;/strong&gt;: Computes the edge detection in the 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;yy &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
-direction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Final step&lt;/strong&gt;: The results from both threads are combined to produce the final edge map, &lt;strong&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;GG &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🖼️ Results
&lt;/h3&gt;

&lt;p&gt;Here are examples of processed images using this method. The left column shows the original images, and the right column presents the edge-detected outputs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Original&lt;/th&gt;
&lt;th&gt;Processed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe400659a75ruxpl1msmc.png" alt="Coins" width="300" height="246"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk0wbi3mn3way6279z8r5.png" alt="Coins" width="300" height="246"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lkve3x55rteso7i1e9f.png" alt="Dog" width="800" height="802"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpphx0cfodvbuo8fgyhi7.png" alt="Dog" width="800" height="802"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2orx9tgsd8uzcjim09q2.jpg" alt="Lena" width="800" height="548"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe35gnm5a0qn7t96aop9r.jpg" alt="Lena" width="800" height="548"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnzo6u233v6shg0d3wvv3.png" alt="UFRN" width="800" height="900"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh0e1pom9tb3bl8xjc41o.png" alt="UFRN" width="800" height="900"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🎯 Conclusion
&lt;/h3&gt;

&lt;p&gt;By leveraging the power of Ruby threads, this project demonstrates how to efficiently apply edge detection to images in both the horizontal (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
) and vertical (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;yy &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
) directions. The results show how edge detection enhances the structural details of images, making them more suitable for tasks like object recognition and segmentation. This approach not only speeds up the processing but also makes it scalable for larger datasets.&lt;/p&gt;

&lt;p&gt;For more details and to explore the code, visit the &lt;a href="https://github.com/ErnaneJ/ruby-edge-detection-threads" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;. 🎉&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>minimagick</category>
      <category>threads</category>
      <category>reliefdetection</category>
    </item>
    <item>
      <title>[pt-BR] Guia Prático: Explorando o Poder da Gem ActiveRecord no Ruby - Sem Framework 🚀</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Sat, 30 Mar 2024 02:40:44 +0000</pubDate>
      <link>https://dev.to/ernanej/pt-br-guia-pratico-explorando-o-poder-da-gem-activerecord-no-ruby-sem-framework-2dfg</link>
      <guid>https://dev.to/ernanej/pt-br-guia-pratico-explorando-o-poder-da-gem-activerecord-no-ruby-sem-framework-2dfg</guid>
      <description>&lt;h1&gt;
  
  
  [pt-BR] Guia Prático: Explorando o Poder da Gem ActiveRecord no Ruby - Sem Framework 🚀
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Recentemente, tive contato com alguns novos entusiastas do Ruby que provavelmente em breve estarão explorando o Rails, dado o caminho que estão seguindo. Acredito que, uma vez que tenhamos uma compreensão básica de Ruby e a linguagem devidamente instalada, é vantajoso explorarmos o Active Record, uma poderosa gem que simplifica significativamente as operações no banco de dados. Dedico este conteúdo a vocês.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introdução 🎉
&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;gem&lt;/em&gt; Ruby &lt;code&gt;ActiveRecord&lt;/code&gt; é uma ferramenta poderosa que oferece abstrações simplificadas para interagir com bancos de dados, permitindo uma troca fácil do &lt;em&gt;back-end&lt;/em&gt; do banco de dados, por exemplo, migrando de &lt;code&gt;SQLite3&lt;/code&gt; para &lt;code&gt;MySQL&lt;/code&gt; sem a necessidade de alterar o código. Esta gem possui suporte integrado para abstrações de banco de dados para &lt;code&gt;SQLite3&lt;/code&gt;, &lt;code&gt;MySQL&lt;/code&gt; e &lt;code&gt;PostgreSQL&lt;/code&gt;, e uma das suas principais vantagens é a necessidade mínima de configuração. Embora o &lt;code&gt;ActiveRecord&lt;/code&gt; seja amplamente utilizado com o framework &lt;a href="https://rubyonrails.org/" rel="noopener noreferrer"&gt;Ruby-on-Rails&lt;/a&gt;, ele também pode ser empregado com o Sinatra ou até mesmo de forma independente, sem qualquer estrutura web. Aqui iremos nos concentrar em demonstrar o uso do &lt;code&gt;ActiveRecord&lt;/code&gt; de forma autônoma, fora de qualquer estrutura específica. 🌟&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparando o Projeto 🛠️
&lt;/h2&gt;

&lt;p&gt;Para desenvolver este tutorial de forma organizada e facilitar a compreensão e consulta posterior do conteúdo, adotarei uma certa estrutura de pastas e arquivos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando uma Pasta para o Projeto 📂
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;ruby-and-activerecord
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inicializando o Bundle 📦
&lt;/h3&gt;

&lt;p&gt;Para gerenciar as gems que serão utilizadas, recomenda-se o uso do Bundler. Neste tutorial utilizaremos o Gemfile para escopar as dependências do projeto. Para começar, execute o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso criará um novo Gemfile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instalando a Gem ActiveRecord 💎
&lt;/h3&gt;

&lt;p&gt;Para instalar a gem ActiveRecord, você pode utilizar a ferramenta &lt;code&gt;gem&lt;/code&gt; ou o gerenciador de pacotes do seu sistema, caso esteja disponível. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Instalando com gem&lt;/span&gt;
gem &lt;span class="nb"&gt;install &lt;/span&gt;activerecord

&lt;span class="c"&gt;# No Ubuntu&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;ruby-activerecord
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entretanto, neste tutorial, utilizaremos o &lt;code&gt;Gemfile&lt;/code&gt; para organizar as dependências do projeto. Para isso, execute o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle add activerecord
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você também pode adicionar diretamente ao seu &lt;code&gt;Gemfile&lt;/code&gt;. Ele ficará semelhante ao conteúdo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# frozen_string_literal: true

source "https://rubygems.org"

gem "activerecord", "~&amp;gt; 7.1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois basta executar o &lt;code&gt;bundle install&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consultando a Documentação 📚
&lt;/h3&gt;

&lt;p&gt;Antes, durante ou após a leitura deste tutorial (ou qualquer outro), é altamente recomendável que você consulte e verifique as informações diretamente na documentação oficial. Você pode usar o comando &lt;code&gt;ri&lt;/code&gt; ou acessar a &lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Base.html" rel="noopener noreferrer"&gt;documentação online&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ri ActiveRecord
ri ActiveRecord::Base
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Estabelecendo Conexão com o Banco de Dados 🎲
&lt;/h2&gt;

&lt;p&gt;Antes de utilizar qualquer modelo, é essencial estabelecer uma conexão com o banco de dados. Como mencionado anteriormente, há uma grande praticidade em conectar uma aplicação ao &lt;code&gt;ActiveRecord&lt;/code&gt; com diferentes tipos de banco de dados, como &lt;code&gt;SQLite3&lt;/code&gt;, &lt;code&gt;MySQL&lt;/code&gt; ou &lt;code&gt;PostgreSQL&lt;/code&gt;, por exemplo. Abaixo, apresento exemplos para três adaptadores diferentes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'active_record'&lt;/span&gt;

&lt;span class="c1"&gt;# SQLite3&lt;/span&gt;
&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;establish_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;adapter: &lt;/span&gt;&lt;span class="s1"&gt;'sqlite3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;database: &lt;/span&gt;&lt;span class="s1"&gt;'test.db'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# MySQL&lt;/span&gt;
&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;establish_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;adapter: &lt;/span&gt;&lt;span class="s1"&gt;'mysql2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;host: &lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;username: &lt;/span&gt;&lt;span class="s1"&gt;'seu_nome_de_usuario_do_banco_de_dados'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="s1"&gt;'sua_senha_do_banco_de_dados'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;database: &lt;/span&gt;&lt;span class="s1"&gt;'seu_nome_do_banco_de_dados'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# PostgreSQL&lt;/span&gt;
&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;establish_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;adapter: &lt;/span&gt;&lt;span class="s1"&gt;'postgresql'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;host: &lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;username: &lt;/span&gt;&lt;span class="s1"&gt;'seu_nome_de_usuario_do_banco_de_dados'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="s1"&gt;'sua_senha_do_banco_de_dados'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;database: &lt;/span&gt;&lt;span class="s1"&gt;'seu_nome_do_banco_de_dados'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para este tutorial, estaremos utilizando o SQLite, mas você pode optar por qualquer adaptador que desejar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instalando a Gem SQLite3 🪶
&lt;/h3&gt;

&lt;p&gt;Para utilizar o adaptador &lt;code&gt;SQLite3&lt;/code&gt;, é necessário instalar a gem correspondente. Assim como fizemos anteriormente com o &lt;code&gt;ActiveRecord&lt;/code&gt;, faremos o mesmo processo para instalar essa &lt;em&gt;gem&lt;/em&gt;. Nosso &lt;code&gt;Gemfile&lt;/code&gt; ficará assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# frozen_string_literal: true&lt;/span&gt;

&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="s2"&gt;"https://rubygems.org"&lt;/span&gt;

&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"activerecord"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 7.1"&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"sqlite3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.7"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Estabelecendo Conexão com o Banco de Dados SQLite 🪶
&lt;/h3&gt;

&lt;p&gt;Para uma melhor organização, criaremos uma pasta de configurações e dentro dela um arquivo &lt;code&gt;initializer.rb&lt;/code&gt;. Este arquivo será responsável por realizar a conexão com o banco de dados. Para simplificar o processo de configuração, também optaremos por criar um arquivo &lt;code&gt;.yaml&lt;/code&gt; para armazenar as configurações do banco de dados fora do código.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# configurations/initializer.rb&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'yaml'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'active_record'&lt;/span&gt;

&lt;span class="n"&gt;db_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;YAML&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pwd&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'/configurations/database.yaml'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;establish_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E em nosso arquivo &lt;code&gt;database.yaml&lt;/code&gt; teremos as configurações da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# configurations/database.yaml&lt;/span&gt;
&lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sqlite3'&lt;/span&gt;
&lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./database/database.sqlite3'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;ℹ️ Estamos armazenando o banco de dados no caminho &lt;code&gt;./database/database.db&lt;/code&gt;. Se necessário, altere esse caminho ou crie a pasta 'database' na raiz do projeto.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com isso, a conexão está estabelecida. Para testá-la, basta executar o &lt;code&gt;initializer.rb&lt;/code&gt; da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ruby ./configurations/initializer.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se não houver erros, estamos no caminho certo!&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um Modelo 🧑🏼‍💻
&lt;/h2&gt;

&lt;p&gt;Para criar um modelo, basta criar a classe desejada herdando de &lt;code&gt;ActiveRecord::Base&lt;/code&gt;. Os nomes das tabelas são assumidos com base no nome da classe do modelo que está sendo criado. Por exemplo, um modelo chamado &lt;code&gt;User&lt;/code&gt; espera ter uma tabela chamada &lt;code&gt;users&lt;/code&gt;. Um modelo chamado &lt;code&gt;ProfileUser&lt;/code&gt; espera uma tabela chamada &lt;code&gt;profile_users&lt;/code&gt;. Ele converte tudo para minúsculas e adiciona um sublinhado entre as palavras em maiúsculas.&lt;/p&gt;

&lt;p&gt;Para uma melhor organização, criaremos uma pasta adicional na raiz do projeto, onde guardaremos todas as nossas models. Para começarmos, vamos criar uma model de User.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/user.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tecnicamente, isso é tudo que você precisa fazer. Por padrão, ele mapeará os campos existentes do banco de dados para atributos no modelo. Você não precisa definir cada campo no código. No entanto, se desejar, você pode sobrescrever propriedades como o nome da tabela e a chave primária — &lt;em&gt;por sua conta e risco&lt;/em&gt; 😬.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/user.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'user'&lt;/span&gt;
  &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;primary_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'user_id'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Juntando as Peças 🛠️
&lt;/h2&gt;

&lt;p&gt;Vamos criar um arquivo principal para reunir e usar nossos componentes enquanto experimentamos. Portanto, crie um &lt;code&gt;main.rb&lt;/code&gt; na raiz do projeto e adicione o seguinte conteúdo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.rb&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'active_record'&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'./configurations/initializer.rb'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'./models/user'&lt;/span&gt;

&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Ernane'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe que estamos carregando o &lt;code&gt;ActiveRecord&lt;/code&gt;, executando o &lt;code&gt;initializer.rb&lt;/code&gt; para estabelecer a conexão com o banco de dados e importando nossa nova &lt;code&gt;model&lt;/code&gt; de usuário. As próximas linhas são usadas para criar um usuário. Entraremos em detalhes sobre essas instruções em breve.&lt;/p&gt;

&lt;p&gt;Para executar, realizamos a mesma ação que fizemos com o initializer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ruby main.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode notar que recebeu um erro porque nossa tabela &lt;code&gt;users&lt;/code&gt; não existe no banco de dados ainda. Isso ocorre porque, como mencionado, o &lt;code&gt;ActiveRecord&lt;/code&gt; realiza o mapeamento dos atributos do banco de dados em métodos da classe modelo correspondente. Se a tabela não existir, ocorrerá o erro que você deve estar vendo agora.&lt;/p&gt;

&lt;p&gt;Para criar a tabela, você pode executar a criação manualmente em SQL. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;admin&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;tshirt_size&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou, se quiser adiantar um pouco no conteúdo, você pode criar uma migração.&lt;/p&gt;

&lt;p&gt;Para uma melhor organização, mais uma vez, criaremos uma nova pasta chamada &lt;code&gt;migrations&lt;/code&gt; dentro da nossa pasta de banco de dados. Lá, adicionaremos uma migração, que nada mais é do que um arquivo Ruby. Por exemplo, para o nosso modelo de usuário:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./database/migrations/create_user_table.rb&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'./configurations/initializer.rb'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreateUserTable&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;6.0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;change&lt;/span&gt;
    &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="ss"&gt;:age&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boolean&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="ss"&gt;:tshirt_size&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timestamps&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;CreateUserTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;migrate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:up&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para executar essa migração, basta usar o Ruby no seu terminal como de costume.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ruby ./database/migrations/create_user_table.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Essa não é a melhor forma de lidar com migrações em um projeto. Você pode criar uma tarefa Rake para executar suas migrações, facilitando o processo. No entanto, não vou me ater a esse tópico agora, pois não é o objetivo dessa publicação.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Uso do ActiveRecord 🤩
&lt;/h2&gt;

&lt;p&gt;Agora que tudo está pronto, podemos executar novamente nosso arquivo principal. Como agora temos a tabela criada, o erro anterior desaparecerá e poderemos realizar nossas primeiras manipulações com o &lt;code&gt;ActiveRecord&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Listando Colunas da Tabela 📋
&lt;/h3&gt;

&lt;p&gt;Depois de criar um modelo, você pode acessar as colunas como objetos vinculados ao modelo. Aqui está um exemplo que irá imprimir as colunas de uma tabela:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./examples/listing_columns.rb&lt;/span&gt;

&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; =&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando Novos Registros 🆕
&lt;/h3&gt;

&lt;p&gt;Existem várias maneiras de criar um novo registro:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criar um novo objeto e chamar explicitamente o método &lt;code&gt;.save()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Usar um bloco para preencher o objeto e chamar o método &lt;code&gt;.save()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Chamar &lt;code&gt;.create()&lt;/code&gt; que criará e salvará em uma única etapa;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./examples/creating_new_records.rb&lt;/span&gt;

&lt;span class="c1"&gt;# Criar um novo objeto de usuário e então salvá-lo para armazenar no banco de dados&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'ErnaneDois'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s1"&gt;'teste0@teste.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;admin: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;tshirt_size: &lt;/span&gt;&lt;span class="s1"&gt;'M'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;

&lt;span class="c1"&gt;# Usar um bloco para preencher o objeto e então salvar&lt;/span&gt;
&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ErnaneUm'&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'teste1@teste.com'&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tshirt_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'M'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;

&lt;span class="c1"&gt;# Criar e salvar em uma única etapa com ".create()"&lt;/span&gt;
&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'ErnaneTres'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s1"&gt;'teste2@teste.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;admin: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;tshirt_size: &lt;/span&gt;&lt;span class="s1"&gt;'M'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Encontrando Registros 🔍
&lt;/h3&gt;

&lt;p&gt;Existem muitos métodos que você pode usar para consultar registros. Alguns deles incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;first()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;last()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;second()&lt;/code&gt;, &lt;code&gt;third()&lt;/code&gt;, &lt;code&gt;fourth()&lt;/code&gt;, &lt;code&gt;fifth()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;all()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;where()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;find_by()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;find_by_sql()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;find_by_*()&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./examples/finding_records.rb&lt;/span&gt;

&lt;span class="c1"&gt;# Obter o primeiro usuário&lt;/span&gt;
&lt;span class="n"&gt;primeiro_usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;primeiro_usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;

&lt;span class="c1"&gt;# Obter o último usuário&lt;/span&gt;
&lt;span class="n"&gt;ultimo_usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;ultimo_usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;

&lt;span class="c1"&gt;# Também disponível: User.second, User.third, User.fourth, User.fifth&lt;/span&gt;

&lt;span class="c1"&gt;# Encontrar todos os usuários que correspondem à consulta e depois pegar o primeiro da lista&lt;/span&gt;
&lt;span class="n"&gt;adultos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'age &amp;gt; ?'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Adultos: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;adultos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Obter todos os usuários&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Total de usuários: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Encontrar o primeiro usuário que corresponde à consulta&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'nomeNovo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;

&lt;span class="c1"&gt;# Obter todos os usuários e classificar&lt;/span&gt;
&lt;span class="n"&gt;usuarios_classificados&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;age: :desc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;usuarios_classificados&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Você pode combinar vários campos dinamicamente em consultas find_by_*&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_name_and_age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nomeNovo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; tem &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; anos"&lt;/span&gt;

&lt;span class="c1"&gt;# Consultar usando SQL personalizado&lt;/span&gt;
&lt;span class="n"&gt;usuarios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'select * from users'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;usuarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; tem &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; anos"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acesse o &lt;a href="https://guides.rubyonrails.org/active_record_querying.html" rel="noopener noreferrer"&gt;Guia do Ruby&lt;/a&gt; para obter mais informações.&lt;/p&gt;

&lt;h3&gt;
  
  
  Atualizando Registros 🔄
&lt;/h3&gt;

&lt;p&gt;Para atualizar um registro, você também tem algumas opções. Uma delas é obter o registro, modificá-lo e, em seguida, chamá-lo explicitamente. Outra opção é chamar o método &lt;code&gt;update()&lt;/code&gt; para fazer a alteração e salvar em uma única ação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./examples/updating_records.rb&lt;/span&gt;

&lt;span class="c1"&gt;# Atualizar modificando um objeto de usuário e chamando explicitamente ".save"&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'novoNome'&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;

&lt;span class="c1"&gt;# Atualizar e salvar em uma única etapa&lt;/span&gt;
&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'nomeNovo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Excluindo Registros ␡
&lt;/h3&gt;

&lt;p&gt;Para excluir um registro, você pode acessar um registro individual ou chamar métodos para excluir todos os registros. Aqui estão alguns exemplos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./examples/deleting_records.rb&lt;/span&gt;

&lt;span class="c1"&gt;# Maneira funcional, mas ineficiente, de excluir todos os registros:&lt;/span&gt;
&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# ou ainda =&amp;gt; User.all.each(&amp;amp;:delete)&lt;/span&gt;

&lt;span class="c1"&gt;# Opção mais eficiente:&lt;/span&gt;
&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Funções de Retorno de Chamada 👀
&lt;/h3&gt;

&lt;p&gt;Existem vários métodos que você pode adicionar em modelo que serão acionados automaticamente quando determinadas ações forem executadas, como &lt;code&gt;criar&lt;/code&gt;, &lt;code&gt;atualizar&lt;/code&gt; ou &lt;code&gt;excluir&lt;/code&gt; um registro, além de &lt;code&gt;consultar&lt;/code&gt; um registro.&lt;/p&gt;

&lt;p&gt;Saiba mais sobre retornos de chamada em &lt;a href="https://guides.rubyonrails.org/active_record_callbacks.html#available-callbacks" rel="noopener noreferrer"&gt;Ruby on Rails Guides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Esses métodos de retorno de chamada podem ser classificados em diferentes categorias:&lt;/p&gt;

&lt;h4&gt;
  
  
  📍 Ação de Exclusão:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;before_destroy&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;after_destroy&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📍 Ações de Criação:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;before_create&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;after_create&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📍 Ações de Criação e Atualização:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;before_validation&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;after_validation&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;before_update&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;after_update&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;before_save&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;after_save&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📍 Ações de Consulta:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;after_initialize&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;after_find&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📍 Ações de Criação, Atualização e Exclusão:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;after_commit&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;after_rollback&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aqui está um exemplo de como configurar um retorno de chamada usando blocos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/user.rb&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;before_create&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Prestes a criar o usuário: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Novo objeto de usuário criado: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outra maneira é especificar as funções de retorno de chamada a serem executadas usando &lt;code&gt;symbols&lt;/code&gt;, operando em &lt;code&gt;self&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/user.rb&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;before_create&lt;/span&gt; &lt;span class="ss"&gt;:before_create_callback&lt;/span&gt;
  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="ss"&gt;:after_create_callback&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;before_create_callback&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Prestes a criar o usuário: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;after_create_callback&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Novo objeto de usuário criado: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Ernane'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Aciona os callbacks definidos anteriormente&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os retornos de chamada "&lt;em&gt;around&lt;/em&gt;" (&lt;code&gt;around_create&lt;/code&gt;, por exemplo) são um pouco mais complexos. Eles permitem que você execute código antes e depois de uma ação, podendo ser úteis para &lt;em&gt;benchmarking&lt;/em&gt; de desempenho, por exemplo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/user.rb&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;around_create&lt;/span&gt; &lt;span class="ss"&gt;:around_create_callback&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;around_create_callback&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Um usuário está prestes a ser criado'&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="c1"&gt;# Aguarde até que o salvamento tenha ocorrido&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Um usuário foi criado.'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Ernane'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Aciona o callback definido anteriormente&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validação de Campos ✅
&lt;/h3&gt;

&lt;p&gt;Ao adicionar validações a um modelo, você garante que qualquer objeto salvo atenda a determinados padrões. Existem várias validações integradas disponíveis. Aqui estão alguns exemplos de validações que você pode aplicar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Garantir que um campo esteja vazio ou não vazio;&lt;/li&gt;
&lt;li&gt;Garantir que um campo contenha um valor exclusivo;&lt;/li&gt;
&lt;li&gt;Garantir o comprimento de um campo;&lt;/li&gt;
&lt;li&gt;Garantir que um campo seja um valor numérico;&lt;/li&gt;
&lt;li&gt;Garantir que um campo corresponda a uma expressão regular;&lt;/li&gt;
&lt;li&gt;Implementar funções de validação personalizadas (&lt;em&gt;o céu é o limite, ou quase&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Após aplicar as validações, você pode chamar os métodos &lt;code&gt;.valid?&lt;/code&gt; e &lt;code&gt;.invalid?&lt;/code&gt; no modelo para realizar as validações e gerar mensagens de erro, que podem ser acessadas no modelo. A chamada também executará as validações e gerará mensagens de erro. Ela retornará &lt;code&gt;falso&lt;/code&gt; se a operação não for bem-sucedido. Você pode aprender mais sobre validações no &lt;a href="https://guides.rubyonrails.org/active_record_validations.html" rel="noopener noreferrer"&gt;Guia de Validações do ActiveRecord&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/user.rb&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;

  &lt;span class="c1"&gt;# ...&lt;/span&gt;

  &lt;span class="c1"&gt;# Garantir que os campos de nome e idade estejam presentes&lt;/span&gt;
  &lt;span class="n"&gt;validates_presence_of&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:age&lt;/span&gt;

  &lt;span class="c1"&gt;# Garantir que um campo seja único&lt;/span&gt;
  &lt;span class="n"&gt;validates_uniqueness_of&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;

  &lt;span class="c1"&gt;# Usar uma expressão regular para limitar os valores do campo&lt;/span&gt;
  &lt;span class="n"&gt;validates_format_of&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="sr"&gt;/\A[a-zA-Z]+\z/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s2"&gt;"Apenas letras são permitidas"&lt;/span&gt;

  &lt;span class="c1"&gt;# Garantir que um campo esteja vazio&lt;/span&gt;
  &lt;span class="n"&gt;validates_absence_of&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt;

  &lt;span class="c1"&gt;# Garantir que um valor tenha um comprimento específico&lt;/span&gt;
  &lt;span class="n"&gt;validates_length_of&lt;/span&gt; &lt;span class="ss"&gt;:credit_card&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;is: &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;

  &lt;span class="c1"&gt;# Garantir que o valor seja de um tipo específico&lt;/span&gt;
  &lt;span class="n"&gt;validates_numericality_of&lt;/span&gt; &lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only_integer: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;

  &lt;span class="c1"&gt;# Garantir um comprimento mínimo e máximo&lt;/span&gt;
  &lt;span class="n"&gt;validates_length_of&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;minimum: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;maximum: &lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;

  &lt;span class="c1"&gt;# Outra forma de especificar o comprimento&lt;/span&gt;
  &lt;span class="n"&gt;validates_length_of&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;in: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;

  &lt;span class="c1"&gt;# Garantir que o valor corresponda a um conjunto específico&lt;/span&gt;
  &lt;span class="n"&gt;validates_inclusion_of&lt;/span&gt; &lt;span class="ss"&gt;:tshirt_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;in: &lt;/span&gt;&lt;span class="sx"&gt;%w(PP P M G GG XG)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s2"&gt;"Tamanho de camiseta inválido: %{value}"&lt;/span&gt;

  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./examples/validating_records.rb&lt;/span&gt;

&lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test'&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Ernane123"&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;50.5&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tshirt_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'XM'&lt;/span&gt;

&lt;span class="c1"&gt;# Alternativamente, use `.valid?` ou `.invalid?` para gerar erros&lt;/span&gt;
&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;
  &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este exemplo garantirá que os dados inseridos no objeto de usuário atendam aos critérios de validação definidos no modelo. Se houver algum erro de validação, ele será exibido na saída.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transações em Bancos de Dados 🎲
&lt;/h3&gt;

&lt;p&gt;O uso de transações em bancos de dados permite executar várias operações de forma segura, garantindo que todas sejam realizadas ou nenhuma delas seja concluída. Por exemplo, ao realizar operações complexas que envolvem múltiplas atualizações ou inserções, é crucial garantir a integridade do banco de dados, evitando estados inconsistentes.&lt;/p&gt;

&lt;p&gt;Você pode criar e executar transações em blocos de código utilizando o método &lt;code&gt;transaction&lt;/code&gt; fornecido pelo &lt;code&gt;ActiveRecord&lt;/code&gt;. Veja um exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./examples/testing_transactions.rb&lt;/span&gt;

&lt;span class="c1"&gt;# Exemplo 1: &lt;/span&gt;
&lt;span class="c1"&gt;# - Deve tentar mudar o nome e funcionar. &lt;/span&gt;
&lt;span class="c1"&gt;# - Deve tentar mudar a idade e deve falhar pois o valor tem que ser inteiro (validação presente no modelo). &lt;/span&gt;
&lt;span class="c1"&gt;# - Como falhou, as alterações já realizadas, mesmo que em sucesso, serão revertidas.&lt;/span&gt;

&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Antes 1 =&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt;
    &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'novonome'&lt;/span&gt; &lt;span class="c1"&gt;# deve funcionar&lt;/span&gt;
    &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save!&lt;/span&gt;

    &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;50.6&lt;/span&gt; &lt;span class="c1"&gt;# deve falhar&lt;/span&gt;
    &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save!&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RecordInvalid&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Erro ao salvar: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ❌ Nada muda&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Depois 1 (nada muda) =&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt;

&lt;span class="c1"&gt;# Exemplo 2: &lt;/span&gt;
&lt;span class="c1"&gt;# - Deve tentar mudar o nome e idade e funcionar. &lt;/span&gt;
&lt;span class="c1"&gt;# - Como não falhou, as alterações persistem.&lt;/span&gt;

&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Antes 2 =&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt;
  &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'novonome'&lt;/span&gt; &lt;span class="c1"&gt;# deve funcionar&lt;/span&gt;
  &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save!&lt;/span&gt;

  &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;  &lt;span class="c1"&gt;# deve funcionar&lt;/span&gt;
  &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ✅ As alterações persistem&lt;/span&gt;
&lt;span class="c1"&gt;# Agora nome e idade foram alterados&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Depois 2 =&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Funciona perfeitamente."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro do bloco de transação, você pode capturar exceções para tratamento específico ou para permitir que a transação continue. Se necessário, você pode relançar exceções para sair da transação.&lt;/p&gt;

&lt;p&gt;Além disso, você não está limitado a operar apenas no modelo associado ao bloco de transação. Você pode chamar o método &lt;code&gt;transaction&lt;/code&gt; em qualquer modelo ou instância de modelo para iniciar uma transação específica para aquele objeto.&lt;/p&gt;

&lt;p&gt;O uso de transações é essencial para garantir a integridade e consistência dos dados em aplicações que envolvem operações críticas no banco de dados.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relacionamentos ↔️
&lt;/h3&gt;

&lt;p&gt;Associar modelos uns aos outros é um aspecto fundamental do &lt;code&gt;ActiveRecord&lt;/code&gt;. Estes incluem relacionamentos como &lt;code&gt;um para um&lt;/code&gt;, &lt;code&gt;um para muitos&lt;/code&gt; e &lt;code&gt;muitos para muitos&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Os relacionamentos disponíveis entre os modelos são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pertence a (&lt;code&gt;belongs_to&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;tem um (&lt;code&gt;has_one&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;tem muitos (&lt;code&gt;has_many&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;tem muitos através de (&lt;code&gt;has_many :through&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;tem um através de (&lt;code&gt;has_one :through&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;tem e pertence a muitos (&lt;code&gt;has_and_belongs_to_many&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Há uma espécie de '&lt;em&gt;mágica&lt;/em&gt;' ✨ que acontece quando se trata da nomeação de tabelas. Você pode substituir os nomes das tabelas e os nomes das colunas de chave estrangeira, mas é recomendado seguir as convenções para evitar configurações extras. Por exemplo, se um &lt;code&gt;Perfil&lt;/code&gt; pertence a um &lt;code&gt;Usuário&lt;/code&gt;, ele assume que existem tabelas de usuários e perfis, e a tabela de perfis terá uma coluna &lt;code&gt;user_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tabelas de ligação para relacionamentos &lt;code&gt;muitos para muitos&lt;/code&gt; usam o nome de ambos os modelos em ordem alfabética. Por exemplo, se um &lt;strong&gt;Usuário&lt;/strong&gt; tem um relacionamento muitos para muitos com um &lt;strong&gt;Departamento&lt;/strong&gt;, então a tabela de ligação é esperada para ser nomeada &lt;code&gt;departments_users&lt;/code&gt; e conter colunas &lt;code&gt;user_id&lt;/code&gt; e &lt;code&gt;department_id&lt;/code&gt; que fazem referência às tabelas denominadas &lt;code&gt;departments&lt;/code&gt; e &lt;code&gt;users&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Neste exemplo, preste atenção especial à singularidade ou pluralidade das palavras usadas nos nomes dos modelos, nomes dos relacionamentos e nomes das tabelas do banco de dados. Ao usar um relacionamento &lt;code&gt;has_and_belongs_to_many&lt;/code&gt;, a tabela de ligação usa plurais de ambos os nomes em ordem alfabética.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nessa etapa será necessário criar novas tabelas para que o exemplo funcione pois precisamos de mais tabelas para relacionar. Dessa forma, você pode se aventurar criando-as manualmente ou executar a migration presente &lt;a href="https://github.com/ErnaneJ/ruby-and-activerecord/blob/main/database/migrations/create_profiles_posts_and_departments_tables.rb" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/user.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;has_one&lt;/span&gt; &lt;span class="ss"&gt;:profile&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt;
  &lt;span class="n"&gt;has_and_belongs_to_many&lt;/span&gt; &lt;span class="ss"&gt;:departments&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/post.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/profile.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Profile&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./models/department.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Department&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;has_and_belongs_to_many&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma, podemos realizar as seguintes execuções:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.rb&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Ernane'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Algumas maneiras de criar o perfil para o usuário:&lt;/span&gt;
&lt;span class="no"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;bio: &lt;/span&gt;&lt;span class="s1"&gt;'ErnaneJ'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;bio: &lt;/span&gt;&lt;span class="s1"&gt;'Hello World! :)'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;bio: &lt;/span&gt;&lt;span class="s1"&gt;'Hello World! :)'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Algumas maneiras de adicionar um post ao usuário (relacionamento um para muitos)&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s1"&gt;'Post de exemplo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s1"&gt;'Outro post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s1"&gt;'Um terceiro post'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Criar os departamentos e relacionamentos (relacionamento muitos para muitos)&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;departments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'TI'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Department&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Vendas'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;users: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;departments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Department&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'RH'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Obtendo os objetos relacionados&lt;/span&gt;
&lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Ernane'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post_ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;department_ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;departments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode ler mais sobre associações acessando o &lt;a href="https://guides.rubyonrails.org/association_basics.html" rel="noopener noreferrer"&gt;Guides&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Migrações 🗄️
&lt;/h3&gt;

&lt;p&gt;Para evitar a necessidade de escrever instruções SQL para criar, modificar e destruir esquemas de banco de dados, o ActiveRecord fornece um mecanismo para realizar migrações. Isso permite que você escreva código Ruby para especificar como deve ser a estrutura do banco de dados sem escrever SQL bruto.&lt;/p&gt;

&lt;p&gt;Existem alguns benefícios nisso. Por exemplo, como comentado anteriormente, você pode usar a mesma migração para criar o esquema de banco de dados para SQLite, MySQL e PostgreSQL, mesmo que as instruções SQL reais possam variar de banco de dados para banco de dados. Ele também permite que você execute atualizações, desmonte e reconstrua facilmente um banco de dados apenas executando os scripts de migração Ruby, que por sua vez podem ser configurados em um &lt;code&gt;Rakefile&lt;/code&gt; por conveniência.&lt;/p&gt;

&lt;h4&gt;
  
  
  Métodos Disponíveis 📋
&lt;/h4&gt;

&lt;p&gt;Ao definir classes de migração, estes são alguns dos métodos disponíveis que você pode usar para executar operações de banco de dados. Você pode ler mais sobre os métodos disponíveis &lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Migration.html" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;create_table()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;change_table()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rename_table()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;drop_table()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_join_table()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;drop_join_table()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add_column()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;change_column()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;change_column_default()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;change_column_null()&lt;/code&gt; &lt;em&gt;(permitir/proibir nulo)&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rename_column()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remove_column()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remove_columns()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add_timestamps()&lt;/code&gt; &lt;em&gt;(created_at e updated_at)&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remove_timestamps()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add_foreign_key()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remove_foreign_key()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add_index()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rename_index()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remove_index()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add_reference()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remove_reference()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Diferença Entre CHANGE() e UP()/DOWN() ⁉️
&lt;/h4&gt;

&lt;p&gt;No início, pode ser um pouco confuso entender a necessidade desses dois métodos e você também pode estar se perguntando. Basicamente, se você definir migrações usando o método &lt;code&gt;change&lt;/code&gt;, ele determinará automaticamente o que precisa ser feito para que as migrações &lt;code&gt;up&lt;/code&gt; e &lt;code&gt;down&lt;/code&gt; executem ou desfaçam as ações especificadas.&lt;/p&gt;

&lt;p&gt;Se quiser especificar uma ação que funcione apenas em uma direção ou ter mais controle, você poderá definir explicitamente os métodos &lt;code&gt;.up&lt;/code&gt; e &lt;code&gt;.down&lt;/code&gt;. Eu usaria o padrão, &lt;code&gt;change&lt;/code&gt;, a menos que você tenha alguma necessidade especial.&lt;/p&gt;

&lt;h4&gt;
  
  
  Criar e Eliminar Tabelas 🧑🏼‍💻
&lt;/h4&gt;

&lt;p&gt;Este exemplo mostra como fazer uma migração simples que criará uma tabela chamada &lt;code&gt;users&lt;/code&gt; com alguns campos: &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt;, &lt;code&gt;created_at&lt;/code&gt; e &lt;code&gt;updated_at&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Chame o método &lt;code&gt;migrate&lt;/code&gt; da classe de migração para atualizar o banco de dados. Você deve fornecer uma direção (&lt;code&gt;:up&lt;/code&gt; ou &lt;code&gt;:down&lt;/code&gt;) para especificar se deseja executar as alterações ou desfazê-las. Ele determinará automaticamente quais instruções precisam ser executadas para realizar cada ação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreateUserTable&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;5.2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;change&lt;/span&gt;
    &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;
      &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="ss"&gt;:age&lt;/span&gt;
      &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timestamps&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Criar a tabela&lt;/span&gt;
&lt;span class="no"&gt;CreateUserTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;migrate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:up&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Eliminar a tabela&lt;/span&gt;
&lt;span class="no"&gt;CreateUserTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;migrate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:down&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usando no IRB 🖥️
&lt;/h3&gt;

&lt;p&gt;Ao usar o Ruby on Rails, você pode acessar o console do Rails com o comando &lt;code&gt;rails console&lt;/code&gt; para entrar em um ambiente interativo que permite consultar e manipular seus modelos &lt;code&gt;ActiveRecord&lt;/code&gt;. No entanto, se você estiver fora do ambiente Rails, precisará requerer os módulos Ruby onde seus modelos estão definidos.&lt;/p&gt;

&lt;p&gt;Você pode usar o argumento &lt;code&gt;-r&lt;/code&gt; para exigir os módulos desejados na inicialização do IRB. Isso economiza tempo, pois você não precisa digitar os comandos &lt;code&gt;require&lt;/code&gt; manualmente dentro do interpretador.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;irb &lt;span class="nt"&gt;-r&lt;/span&gt; ./models
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma, você pode iniciar o IRB com seus módulos já importados e prontos para uso.&lt;/p&gt;

&lt;p&gt;Alternativamente, como dito, você pode importar manualmente os módulos dentro do IRB digitando os comandos &lt;code&gt;require&lt;/code&gt;. No entanto, criar um script com os comandos de &lt;code&gt;require&lt;/code&gt; economiza tempo e esforço. Uma vez dentro do IRB, você pode usar seus modelos como de costume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;irb&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;001&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"./configurations/initializer.rb"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;002&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"./models/user.rb"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;003&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; User (call 'User.connection' to establish a connection)&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;004&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;User:0x000000010bdb0630 ...&amp;gt; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso permite que você execute consultas e manipulações em seus modelos &lt;code&gt;ActiveRecord&lt;/code&gt; diretamente do console interativo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão 🎉
&lt;/h2&gt;

&lt;p&gt;Após absorver este tutorial, você agora possui um entendimento sólido dos fundamentos do &lt;code&gt;ActiveRecord&lt;/code&gt;. Agora, você deve se sentir confiante para instalar o &lt;code&gt;ActiveRecord&lt;/code&gt;, explorar sua documentação e começar a utilizá-lo em seus projetos Ruby.&lt;/p&gt;

&lt;p&gt;Aqui está um resumo do que foi aprendido:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instalação e configuração inicial do ActiveRecord;&lt;/li&gt;
&lt;li&gt;Definição de modelos e relacionamentos entre eles;&lt;/li&gt;
&lt;li&gt;Execução de consultas para recuperar dados do banco de dados;&lt;/li&gt;
&lt;li&gt;Criação e manipulação de registros no banco de dados;&lt;/li&gt;
&lt;li&gt;Utilização de retornos de chamada para executar ações automáticas em modelos;&lt;/li&gt;
&lt;li&gt;Realização de transações para garantir que várias operações de banco de dados sejam executadas com sucesso ou revertidas em caso de erro;&lt;/li&gt;
&lt;li&gt;Criação e execução de migrações para gerenciar o esquema do banco de dados de forma programática;&lt;/li&gt;
&lt;li&gt;Utilização do ActiveRecord em uma sessão interativa no IRB ou Pry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com esses conhecimentos, você está pronto para aproveitar ao máximo o ActiveRecord em seus projetos Ruby, facilitando o trabalho com bancos de dados e simplificando o desenvolvimento de aplicativos web. Lembre-se de continuar explorando a documentação oficial e praticar com exemplos do mundo real para aprimorar suas habilidades. 🚀&lt;/p&gt;

&lt;p&gt;O &lt;a href="https://github.com/ErnaneJ/ruby-and-activerecord/" rel="noopener noreferrer"&gt;repositório&lt;/a&gt; com os exemplos mencionados neste post está disponível e totalmente aberto a contribuições. Além disso, esta publicação também. Sinta-se à vontade!&lt;/p&gt;

&lt;p&gt;Espero que tenha gostado dessa postagem e que ela tenha te ajudado, de alguma forma, a encontrar ou que você procurava! 💙&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>activerecord</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to develop a svelte component and publish it as a package in NPM</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Sun, 21 May 2023 02:24:14 +0000</pubDate>
      <link>https://dev.to/ernanej/how-to-develop-a-svelte-component-and-publish-it-as-a-package-in-npm-40pc</link>
      <guid>https://dev.to/ernanej/how-to-develop-a-svelte-component-and-publish-it-as-a-package-in-npm-40pc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Publish your favorite svelte component as a package on npm and make it available for use anytime.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we like a certain component that we develop, we end up using and reusing it countless times, in different ways, that is; replicating your files and logic in many different places in the project, or in several other projects, or simply redeploying the same component over and over again. This will work, of course. However, it is not the best way to act in this situation.&lt;/p&gt;

&lt;p&gt;Imagine that you will have to carry out maintenance, or simply change, say, the color of this component. Imagine that there are 10, 100, 200... Well, you will have to make this change in each component present in your project, correct? What if it is already applied to other projects? well, the change should be made too. The problem I think we already understood. But how to solve it?&lt;/p&gt;

&lt;p&gt;When it comes to a project that uses the same technology, in the case that we will see in this post &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt; for example, you can create a component and publish it as a package in NPM and reuse it whenever you need it. That's what we'll see here! for cases where the projects do not share the same technology, this is a matter for another time. But if you like spoilers you can read about WebComponents.&lt;/p&gt;

&lt;h2&gt;
  
  
  What will we develop?
&lt;/h2&gt;

&lt;p&gt;I recently made a simple svelte component - hence the idea of the post - to perform evaluations. It is simply a nest of stars and in it the user will be able to show his satisfaction with such content that the component will return the selected information in its configuration prop. He will be the one we will develop!&lt;/p&gt;

&lt;p&gt;For this, you need to have an account on NPM, have NodeJs and NPM installed on your machine and be patient to venture out!&lt;/p&gt;

&lt;h2&gt;
  
  
  Initializing the project
&lt;/h2&gt;

&lt;p&gt;The first step, like any project, is to create a directory for it. let's go!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;svelte-star-rating
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;svelte-star-rating
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can actually initialize our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a &lt;code&gt;package.json&lt;/code&gt; file and will automatically fill in some information about the package we are developing like name, author, description, etc... the &lt;code&gt;-y&lt;/code&gt; flag will perform a short auto-fill. If you want to do it manually run without it. But don't worry, you can always change package.json when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing required dependencies
&lt;/h2&gt;

&lt;p&gt;The next step is to install the necessary development dependencies of our package. That way, notice that package.json will add the dev dependencies section. In addition, I will take the opportunity to make some changes, such as name, author, keywords, etc. Feel free to fill in as you see fit.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;package.json&lt;/code&gt; should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@ernane/svelte-star-rating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Simple component to assign scores based on stars."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"homepage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/ErnaneJ/svelte-star-rating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bugs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/ErnaneJ/svelte-star-rating/issues"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git+https://github.com/ErnaneJ/svelte-star-rating.git"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"svelte"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"star"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"ratting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"component"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"sapper"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ernane &amp;lt;ernane.junior25@gmail.com&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rollup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.39.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rollup-plugin-node-resolve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rollup-plugin-svelte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"svelte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.32.3"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Component creation
&lt;/h2&gt;

&lt;p&gt;As usual, I create my logic files usually in a subdirectory named &lt;code&gt;src&lt;/code&gt;, I'll follow that pattern here. In this way, we will create an &lt;code&gt;index.js&lt;/code&gt; file, it will be the starting point of our component.&lt;/p&gt;

&lt;p&gt;Basically we will import the main component of our package and export it as default in index. It will be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SvelteStarRating&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./SvelteStarRating.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;SvelteStarRating&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a consequence we will now have to create the file, which will be our svelte component itself, &lt;code&gt;SvelteStarRating.svelte&lt;/code&gt;. To test it, let's just put a test message at the moment!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- src/SvelteStarRating.svelte --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello World! It's my first package svelte component! ✨ SvelteStarRating ✨&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this file we will have all the logic and implementation of our package. In it we will add styles, necessary imports, among other things.. Let's go ahead, we'll be back in it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Formalizing structure
&lt;/h2&gt;

&lt;p&gt;Now that we have the main structure of our component, we need to formalize it in our package.json. For this, we will need to make some more changes to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/index.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/index.mjs"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"svelte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src/index.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rollup -c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rollup -c -w"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;    
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since this part is a bit tricky, let's see what it's actually doing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;main&lt;/code&gt; we define what will be the output after the execution of the compilation script,&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;module&lt;/code&gt; we define the same, but as output an &lt;code&gt;mjs&lt;/code&gt; extension file so that Node can differentiate it among the modules created with &lt;code&gt;CommonJS&lt;/code&gt; and &lt;code&gt;ES6&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;svelte&lt;/code&gt;, we are defining the path of our main file, the &lt;code&gt;index.js&lt;/code&gt; that we created earlier.&lt;/li&gt;
&lt;li&gt;And, finally, &lt;code&gt;scripts&lt;/code&gt; will be the commands used for execution and compilation in development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that the dist subdirectory, which we specified in the first two commands, does not exist as it will be automagically generated ✨.&lt;/p&gt;

&lt;p&gt;After these small changes our &lt;code&gt;package.json&lt;/code&gt; will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@ernane/svelte-star-rating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Simple component to assign scores based on stars."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/index.mjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"svelte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src/index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rollup -c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rollup -c -w"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"homepage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/ErnaneJ/svelte-star-rating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bugs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/ErnaneJ/svelte-star-rating/issues"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git+https://github.com/ErnaneJ/svelte-star-rating.git"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"svelte"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"star"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"ratting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"component"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"sapper"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ernane &amp;lt;ernane.junior25@gmail.com&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rollup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.39.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rollup-plugin-node-resolve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rollup-plugin-svelte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"svelte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.32.3"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the rollup.config.js file
&lt;/h2&gt;

&lt;p&gt;You are probably already familiar with this file because it is Svelte. But basically we perform the basic build configuration of our simple project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;svelte&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rollup-plugin-svelte&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rollup-plugin-node-resolve&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./package.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/AtButton.svelte&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;output&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="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;umd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;svelte&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;resolve&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;Wow! Package successfully configured for use. 🥳&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing component locally
&lt;/h2&gt;

&lt;p&gt;Before we publish our new component on &lt;code&gt;NPM&lt;/code&gt;, it's always good to test it to see how it really is and if its result is satisfactory. For this, we can use it on our machine even before we send it for publication. For this, let's create, in parallel, a simple project in Svelte. For this case, I'll use &lt;code&gt;svelte-playground&lt;/code&gt; itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx degit sveltejs/template svelte-playground
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we access the cloned project and install two initial dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;svelte-playground
&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in order to use our component as an npm package and apply it to this project, we can run the following command in the directory of our &lt;code&gt;svelte-star-rating&lt;/code&gt; package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;link&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With it we will get a response similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm WARN svelte-star-rating@1.0.0 No repository field.&lt;/span&gt;

&lt;span class="c"&gt;# audited 17 packages in 0.711s&lt;/span&gt;

&lt;span class="c"&gt;# 3 packages are looking for funding&lt;/span&gt;
&lt;span class="c"&gt;#   run npm fund for details&lt;/span&gt;

&lt;span class="c"&gt;# found 0 vulnerabilities&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, now in the &lt;code&gt;svelte-playground&lt;/code&gt; test project we can run the same command, but now, going to the directory of our new package on our machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;link&lt;/span&gt; /path/svelte-star-rating
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That way we can use our component as a package locally, and best of all, in realtime!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using component locally
&lt;/h2&gt;

&lt;p&gt;Access the test project we created, &lt;code&gt;svelte-playground&lt;/code&gt;, and run the project under development using the command present in your &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;EThen access the browser at the suggested port and see the application running. After that, we can now apply our component to this project and thus visualize its changes at runtime.&lt;/p&gt;

&lt;p&gt;for that, we go to the &lt;code&gt;src/app.svelte&lt;/code&gt; file, to make some changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- src/app.svelte --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;StarRating&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ernane/svelte-star-rating&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

...
&lt;span class="nt"&gt;&amp;lt;StarRating/&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we'll have our component running locally. Fantastic, isn't it!?&lt;/p&gt;

&lt;p&gt;Now we just have to develop our new component the way we want and check if the changes made match what we want. Here is the current development status of my &lt;a href="https://github.com/ErnaneJ/svelte-star-rating" rel="noopener noreferrer"&gt;svelte-star-rating&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing package in NPM
&lt;/h2&gt;

&lt;p&gt;Great, we already have our component working we would like. And now? well, now we publish it! Publishing is as simple as a push, check it out...&lt;/p&gt;

&lt;p&gt;First, you must be logged into your &lt;code&gt;NPM&lt;/code&gt; account, if you are not or don't know, just follow the steps described &lt;a href="https://docs.npmjs.com/creating-a-new-npm-user-%20account" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After being logged in, and sure you want to publish the first version of your package, just run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm publish &lt;span class="nt"&gt;--access&lt;/span&gt; public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ready! you can access your profile on the NPM page and you will see a new package added! 🎉 Simple no?!&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing new NPM package
&lt;/h2&gt;

&lt;p&gt;You've undoubtedly done this here hundreds of times, or maybe less 😅.. Access your package information that will tell you how to install it. But following the standards you can do it with the simple npm install passing the name, defined in the package.json, of your project!&lt;/p&gt;

&lt;p&gt;i.e,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm i @ernane/svelte-star-rating
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage will be the same as before, import and use. Well, that you already know!&lt;/p&gt;

&lt;p&gt;If you have any questions, here is the &lt;a href="https://github.com/ErnaneJ/svelte-star-rating" rel="noopener noreferrer"&gt;repository&lt;/a&gt; that I used to store the package mentioned here in the post and the link to it already &lt;a href="https://www.npmjs.com/package/@ernane/svelte-star-rating" rel="noopener noreferrer"&gt;published on npm&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this post and that it helped you, in some way, to find what you were looking for! 💙&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.npmjs.com/" rel="noopener noreferrer"&gt;Official NPM documentation&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rollupjs.org/guide/en/" rel="noopener noreferrer"&gt;Rollup Documentation&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://svelte.dev/docs" rel="noopener noreferrer"&gt;Svelte Documentation&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>npm</category>
      <category>svelte</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Configuring Linux terminal to show current branch in versioned directories</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Sun, 21 May 2023 01:59:01 +0000</pubDate>
      <link>https://dev.to/ernanej/configuring-linux-terminal-to-show-current-branch-in-versioned-directories-hgb</link>
      <guid>https://dev.to/ernanej/configuring-linux-terminal-to-show-current-branch-in-versioned-directories-hgb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Make your life easier as a developer and know the current branch in your workspace without complications. And the best? Without installing anything additional!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One of the gifts of a good developer is knowing exactly where he's pushing his changes. Currently, the best way to do this, especially using code versioning with Git, is to validate the current working directory branch. We have a few ways to do this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use git's own command to show the current branch:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git status

&lt;span class="c"&gt;# On branch master&lt;/span&gt;
&lt;span class="c"&gt;# Your branch is up to date with 'origin/master'.&lt;/span&gt;

&lt;span class="c"&gt;# nothing to commit, working tree clea&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or yet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git branch

&lt;span class="c"&gt;# * master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We can install some other third-party terminal (such as &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;Oh My ZSH&lt;/a&gt;), but that's a topic for another post! 😎&lt;/li&gt;
&lt;li&gt;Another option is to simply manipulate your native terminal to show your current branch whenever you have a git-versioned directory. This alternative is what we will see in this post!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Changing settings to display the current branch
&lt;/h2&gt;

&lt;p&gt;Normally, the terminal settings do not show the branch of the current directory if it is versioned by git, and by default only the &lt;code&gt;user&lt;/code&gt;, &lt;code&gt;host&lt;/code&gt; (machine name) and &lt;code&gt;path&lt;/code&gt; (current path) are shown. However, it has some settings that can be manipulated from a variable in its file named &lt;code&gt;PS1&lt;/code&gt;. To do so, simply open the &lt;code&gt;.bashrc&lt;/code&gt; or &lt;code&gt;.bash_profile&lt;/code&gt; file in your preferred text editor and add the following command at the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PS1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\u@\h[\033[01;34m] \w[\033[0;32m]$(__git_ps1 " (%s)")[\033[01;34m]$[\033[00m] '&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To apply the settings, it is necessary to reload the file. We can do this by restarting the system, logging out or simply reloading the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc &lt;span class="c"&gt;# or source ~/.bash_profile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ready! 🎉 We already have our current branch showing in directories that are versioned by git.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional settings
&lt;/h2&gt;

&lt;p&gt;Why not go further? Below I will leave some possible additional color settings, for example, that can be performed to make the present information as relevant as possible to your use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Values:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;\u&lt;/code&gt;: User currently logged on the machine;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\h&lt;/code&gt;: Name of the machine (host), previously registered;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\H&lt;/code&gt;: Full machine name, previously registered;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\w&lt;/code&gt;: Full current working directory;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\W&lt;/code&gt;: Minified current working directory, base name only (last segment);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$(__git_ps1 "%s")&lt;/code&gt;: Current branch if it's in a git-versioned repository, otherwise nothing will be displayed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Colors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blue&lt;/strong&gt;: &lt;code&gt;[\033[0;34m]&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Red&lt;/strong&gt;: &lt;code&gt;[\033[0;31m]&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fluorescent Red&lt;/strong&gt;: &lt;code&gt;[\033[1;31m]&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Green&lt;/strong&gt;: &lt;code&gt;[\033[0;32m]&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fluorescent Green&lt;/strong&gt;: &lt;code&gt;[\033[1;32m]&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong White&lt;/strong&gt;: &lt;code&gt;[\033[1;37m]&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gray&lt;/strong&gt;: &lt;code&gt;[\033[0;37m]&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default&lt;/strong&gt;: &lt;code&gt;[\033[0m]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ready! This is the range of simple and powerful configurations available for use that will make it even easier for you to self-localize in the development process and, in addition, allow customization in the way you want and find valid. Mine looks like this at the time I write this post:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;👾 ~/path/path&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, with emoji! 😬&lt;/p&gt;

&lt;p&gt;What has been shown here is just a little of what is possible to be done. Therefore, as usual, I will leave some links that I used as a reference to write and that you can use to go further on the subject.&lt;/p&gt;

&lt;p&gt;Good reading!&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this post and that it helped you find what you were looking for! 💙&lt;/p&gt;

&lt;h2&gt;
  
  
  Links:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html#Visual-effects" rel="noopener noreferrer"&gt;Prompt-Expansion - Visual-effects&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.maketecheasier.com/8-useful-and-interesting-bash-prompts/" rel="noopener noreferrer"&gt;8 useful and interesting bash prompts&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://slashdot.org/story/01/07/06/122259/what-does-your-command-prompt-look-like" rel="noopener noreferrer"&gt;What does your command prompt look like&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>bash</category>
      <category>git</category>
    </item>
    <item>
      <title>The difference between traditional functions and arrow functions in javascript</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Sun, 21 May 2023 01:43:02 +0000</pubDate>
      <link>https://dev.to/ernanej/a-diferenca-entre-funcoes-tradicionais-e-arrow-functions-no-javascript-7e3</link>
      <guid>https://dev.to/ernanej/a-diferenca-entre-funcoes-tradicionais-e-arrow-functions-no-javascript-7e3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Make no mistake, it's not just the compactness and elegant syntax that differ the ways of declaring functions in Javascript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Arrow functions is a relatively new feature implementing in ES6 (&lt;a href="https://www.w3schools.com/js/js_es6.asp" rel="noopener noreferrer"&gt;ECMAScript 6&lt;/a&gt;) which in our eyes is just a more concise and elegant syntax to declare function expressions in Javascript. Although traditional functions and arrow functions work in a similar way, we must beware of certain differences that may not be noticeable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syntax
&lt;/h2&gt;

&lt;p&gt;The difference in syntax between the two models is notorious, since in the arrow function it becomes possible to considerably reduce the number of lines present in the function declaration, especially if it is already a simple function. See examples:&lt;/p&gt;

&lt;p&gt;Imagine a function that takes a user's name and prints it to the console. In the traditional way, we could declare it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sayMyNane&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`My name is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;sayMyNane&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ernane&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; My name is Ernane.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Already with the arrow functions present from ES6, we could do it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sayMyName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;sayMyNane&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ernane&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; My name is Ernane.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remembering that in the case of arrow functions, the braces are only necessary if an expression is present, the same rule applies for parentheses, since they are only necessary if there is more than one argument to be passed. In this way, we could reduce it even further and write the above example as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sayMyName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt; 

&lt;span class="nf"&gt;sayMyNane&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ernane&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; My name is Ernane.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, isn't it? ✨ in this way, we can see how an arrow function can facilitate the declaration of a certain function because of its syntax and still return the same result as a common declaration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use of the 'this' keyword
&lt;/h2&gt;

&lt;p&gt;Unlike the traditional declaration, arrow functions do not have their own &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" rel="noopener noreferrer"&gt;this&lt;/a&gt; element, as the value of this inside an arrow function remains the same throughout the lifecycle of the function and is always bound to the value of this in the closest traditional parent function.&lt;/p&gt;

&lt;p&gt;Did that get a little weird? 🤔 let me try to uncomplicate with an example:&lt;/p&gt;

&lt;p&gt;Returning to the example used in the previous topic, imagine that we have a &lt;code&gt;person&lt;/code&gt; object that has its name defined as one of its attributes and has a function that prints the name of that particular person to the console. Depending on the type of function used, it will not be able to correctly access the parent object that has the requested &lt;em&gt;name&lt;/em&gt; attribute and, therefore, its return will be &lt;code&gt;undefined&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ernane Ferreira&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}.)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; My name is .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the case of the function being declared in the traditional model, this will work as expected and we will correctly obtain the sought attribute. 🤗&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ernane Ferreira&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; My name is Ernane Ferreira.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Access to arguments
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments" rel="noopener noreferrer"&gt;arguments&lt;/a&gt; object is a local variable available inside all functions and it is what makes the reference possible arguments of a function within the same using the arguments object. However, arrow functions have no link to the &lt;code&gt;arguments&lt;/code&gt; object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showArguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;showArguments&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; ReferenceError: arguments is not defined.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the case of a regular function, we can easily access a list of the arguments passed as a parameter when calling the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showArguments&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; 
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;showArguments&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Arguments(3) [1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using the new operator
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new" rel="noopener noreferrer"&gt;new&lt;/a&gt; operator allows instantiation of a user-defined object type or one of the user-defined types. of internal objects that have a &lt;strong&gt;constructor function&lt;/strong&gt;. Traditional functions are constructible and can be called using the new operator. On the other hand, &lt;em&gt;arrow functions&lt;/em&gt; are callable and not constructible, that is, these functions can never be used as constructor functions and can never be invoked with the &lt;code&gt;new&lt;/code&gt; operator. &lt;/p&gt;

&lt;p&gt;Therefore, for this type of execution in traditional functions, we get the following execution result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;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;new&lt;/span&gt; &lt;span class="nf"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ernane&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Ernane&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As for the &lt;em&gt;arrow functions&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sayMyName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ernane&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Uncaught TypeError: sayMyName is not a constructor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Parameters with duplicate naming
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;arrow functions&lt;/em&gt; do not allow the name of duplicate parameters, but the traditional functions allow depending on the application or non-application of strict mode (&lt;a href="https://developer.mozilla.org/en-US/docs/Web%20/JavaScript/Reference/Strict_mode" rel="noopener noreferrer"&gt;Strict Mode&lt;/a&gt;) in the code implementation. For example, the javascript below is fully valid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTwoNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;addTwoNumbers&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the same code with strict mode applied is no longer valid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTwoNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="c1"&gt;// =&amp;gt; Uncaught SyntaxError: Duplicate parameter name not allowed in this context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using arrow functions, this occurs regardless of whether strict mode is applied. In both cases, the execution is invalid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addTwoNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;// =&amp;gt; SyntaxError: Uncaught SyntaxError: Duplicate parameter name not allowed in this context.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That way, it's always good to pay close attention to the use of &lt;em&gt;arrow functions&lt;/em&gt; instead of traditional functions. Although their syntax is very pleasant, they have some points that we must be careful not to miss.&lt;/p&gt;

&lt;p&gt;In any case, further study on the subject is advisable. As always, I will leave below some recommendation links for the deepening of the theme.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this post and that it helped you find what you were looking for! 💙&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions" rel="noopener noreferrer"&gt;Functions Declarations&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions" rel="noopener noreferrer"&gt;Arrow functions expressions&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3schools.com/js/js_arrow_function.asp" rel="noopener noreferrer"&gt;Javascript Arrow Functions&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3schools.com/js/js_es6.asp" rel="noopener noreferrer"&gt;New Features in ES6&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The 3 best tools I use to validate the meta tags present on my websites</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Sat, 20 May 2023 15:27:43 +0000</pubDate>
      <link>https://dev.to/ernanej/the-3-best-tools-i-use-to-validate-the-meta-tags-present-on-my-websites-1nb3</link>
      <guid>https://dev.to/ernanej/the-3-best-tools-i-use-to-validate-the-meta-tags-present-on-my-websites-1nb3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;It is very important to validate and verify how your article or new web page will be displayed when shared.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When a page on the web is shared — be it on Facebook, Twitter, Linkedin, Instagram, whatsapp, etc. — usually there is some kind of preview of it in the application it is being shared (a title, text snippet, description of what it is about, image or whatever is available). When you are the author of this content, it is extremely important to have a lot of control over the information being displayed, as other people share links to your content.&lt;/p&gt;

&lt;p&gt;Here we will see the main (in my not so humble opinion) tools available for validating and creating meta tags for your website. By the way, the tools that will be mentioned are the ones I use whenever I post new content and I'm not entirely sure how some platforms will display them. 🧐&lt;/p&gt;

&lt;h2&gt;
  
  
  Hey Meta
&lt;/h2&gt;

&lt;p&gt;One of the most important things when adding tags to your website header is to focus mainly on the most essential ones. For social sharing, the most important are &lt;strong&gt;title&lt;/strong&gt; and &lt;strong&gt;description&lt;/strong&gt;. Many services that allow you to share links will use these tags to create cards to preview your content. Even if they have specific tags, like Facebook and Twitter, whenever they don't find their tags, services will look for the generic description and title to know what to display in the share.&lt;/p&gt;

&lt;p&gt;One tool that does a great job with these tags is &lt;a href="https://www.heymeta.com/" rel="noopener noreferrer"&gt;Hey Meta&lt;/a&gt;. In it, you can put any url to be checked and it will show which meta tags it found in its scan or, if possible, try to guess which one should be present. This tool also provides an easy and practical way to add the essential tags on your website from a 'template' that they generate for you on the platform based on your content.&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%2Fss8zj0x9x5vi3jhfh6n8.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%2Fss8zj0x9x5vi3jhfh6n8.png" alt="Hey meta preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Facebook debugger
&lt;/h2&gt;

&lt;p&gt;The company &lt;a href="https://developers.facebook.com/" rel="noopener noreferrer"&gt;Meta&lt;/a&gt;, formerly known as Facebook, developed the &lt;a href="https://ogp.me/" rel="noopener noreferrer"&gt;Open Graph&lt;/a&gt; protocol and Facebook uses it to display its cards view on sharing links. In this way, the Open Graph became a social sharing standard available on the web and this is stated on its home page:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While there are many different technologies and schemes that can be combined, there is no single technology that provides enough information to richly represent any given webpage on the social graph. The Open Graph protocol builds on these existing technologies and gives developers something to implement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As mentioned earlier, Facebook and other networks that use their own meta tags will fall back to base tags if they don't find their own or Open Graph tags (OG tags). However, as also mentioned, OG has become a standard for social sharing, and as such, it becomes important to implement at least the primary OG tags on any page you make available on the internet. The main ones are: &lt;code&gt;og:type&lt;/code&gt;, &lt;code&gt;og: title&lt;/code&gt;, &lt;code&gt;og:description&lt;/code&gt;, &lt;code&gt;og:image&lt;/code&gt; and &lt;code&gt;og:url&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since Facebook is the strongest in this field, it has also taken it upon itself to provide developers with a great tool to &lt;a href="https://developers.facebook.com/tools/debug%20/" rel="noopener noreferrer"&gt;validate OG tags from &lt;strong&gt;any&lt;/strong&gt; URL&lt;/a&gt;. This application provides a way to validate and preview how your pages will appear when shared on Facebook.&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%2Fj3q0nlvao20xwfgbbl46.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%2Fj3q0nlvao20xwfgbbl46.png" alt="Facebook share debugger preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Twitter card validator
&lt;/h2&gt;

&lt;p&gt;Like Facbeook, &lt;a href="https://twitter.com/" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; also has its own separate protocol. Tags for building the Twitter card on its content are only used by the social network, as most other platforms assume OG tags or native tags as the main focus for obtaining data from the associated url.&lt;/p&gt;

&lt;p&gt;The biggest advantage and the main focus of using Twitter cards is having more control over how the card will represent your page on the platform and, for that, the social network has a huge &lt;a href="//https%20://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup"&gt;list of options&lt;/a&gt; to be included. Due to it being platform specific, it is not a problem to stick to native meta tags and OG tags as Twitter will continue to use the available OG and/or native tags. &lt;a href="https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup" rel="noopener noreferrer"&gt;Here&lt;/a&gt; you can check which OG tags present on your page are found and returned by twitter.&lt;/p&gt;

&lt;p&gt;Anyway, Twitter tags are great to use if you want more control over what will appear when you share your page, as the platform has developed a &lt;a href="https://cards-%20dev.twitter.com/validator" rel="noopener noreferrer"&gt;twitter URL validator&lt;/a&gt; to help you verify how your content will appear to users when shared.&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%2Fmabtdfs1yb2tpm0f2g25.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%2Fmabtdfs1yb2tpm0f2g25.png" alt="Twitter card validator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These were the three main tools I use and I find it extremely interesting to verify the information present in my meta tags whenever I publish new content. Of course, there are other very good ones, mainly more complete viewers, but I choose them because Hey Meta helps me to generate the tags in a reliable way and I always use the other two to validate their operation and make adjustments if necessary.&lt;/p&gt;

&lt;p&gt;Use these tools to gain greater control over your content's views when shared. If you know of any other good tools that could complement it, I would be very happy if you share it with me below!&lt;/p&gt;

&lt;p&gt;I hope this post helped you find what you were looking for! 💙&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cards-dev.twitter.com/validator" rel="noopener noreferrer"&gt;Twitter card validator&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup" rel="noopener noreferrer"&gt;Twitter documentation about your tags&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developers.facebook.com/tools/debug/" rel="noopener noreferrer"&gt;Facebook validator&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.heymeta.com/" rel="noopener noreferrer"&gt;Hey Meta Platform&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ogp.me/" rel="noopener noreferrer"&gt;The Open Graph protocol&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developers.google.com/search/docs/advanced/crawling/special-tags" rel="noopener noreferrer"&gt;Meta tags that Google interprets&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>[pt-br] Como alavancar sua produtividade com o Visual Studio Code</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Thu, 21 Apr 2022 18:22:53 +0000</pubDate>
      <link>https://dev.to/ernanej/como-alavancar-sua-produtividade-com-o-visual-studio-code-4802</link>
      <guid>https://dev.to/ernanej/como-alavancar-sua-produtividade-com-o-visual-studio-code-4802</guid>
      <description>&lt;p&gt;Não há dúvidas de que o &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; (VS Code), editor de código de código aberto desenvolvido pela &lt;a href="https://www.microsoft.com/" rel="noopener noreferrer"&gt;Microsoft&lt;/a&gt;, é um dos editores mais queridos da última década devido ser uma ótima ferramenta para o dia a dia não se tratando apenas de código, mas da edição de qualquer tipo de texto. &lt;/p&gt;

&lt;h2&gt;
  
  
  Visual Studio ou Visual Studio Code? 🤔
&lt;/h2&gt;

&lt;p&gt;O &lt;a href="https://visualstudio.microsoft.com/" rel="noopener noreferrer"&gt;Visual Studio&lt;/a&gt; é uma IDE desenvolvida pela Microsoft, dedicada ao .NET Framework e a linguagens robustas como C, C++, C# e F#. Por ser uma solução completa, é uma ferramenta bem mais pesada do que o Visual Studio Code, que trataremos aqui, e que por sua vez trata de funcionalidades mais simples como a fácil edição de código com suporte a várias linguagens de programação, terminal integrado e controle de versão. Sendo, dessa forma, uma ferramenta mais leve. Mas não se engane, muito poderosa! 💪&lt;/p&gt;

&lt;h2&gt;
  
  
  Um mundo aberto de funcionalidades
&lt;/h2&gt;

&lt;p&gt;O VS Code é capaz de fazer muitas coisas que nos ajudam a trabalhar melhor. A princípio ele é, e pode realmente parecer, uma ferramenta muito simples, mas ele possui uma loja de extensões imensa, e que continua crescendo constantemente.&lt;/p&gt;

&lt;p&gt;Ou seja, com essa enorme coleção de extensões, podemos adicionar diversas funcionalidades e personalizações, ao VS Code de forma bem simples e prática. Dessa maneira, ele pode facilmente ser comparado a grandes IDEs pagas. Caso se interesse, facilmente qualquer usuário pode criar uma extensão e publicar na loja. Desse modo, sempre há novas ferramentas que podem ser interessantes para alguém.&lt;/p&gt;

&lt;h2&gt;
  
  
  Atalhos para aumentar sua produtividade
&lt;/h2&gt;

&lt;p&gt;Como qualquer outra ferramenta, é de crucial importância que seus usuários aprendam a manuseá-la com destreza. Quanto mais você se aperfeiçoar nisso, mais fácil será trabalhar com ela em seu cotidiano. Este poderoso editor, assim como a maioria dos outros, possui atalhos que nos tornam mais ágeis na execução de certas atividades, principalmente as mais repetitivas.&lt;/p&gt;

&lt;p&gt;Os atalhos são muitos, mas aqui vamos ver os principais que não podem faltar no seu dia a dia. 🚀&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+K CTRL+0&lt;/strong&gt; ou &lt;strong&gt;CTRL+K CTRL+J&lt;/strong&gt;: Dobrar ou desdobrar todas as funções ou métodos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+G&lt;/strong&gt;: Ir para a linha&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+P&lt;/strong&gt;: Ir para o arquivo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F8&lt;/strong&gt;: Ir para o próximo erro ou aviso&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F12&lt;/strong&gt;: Ir para a definição da função ou método&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALT+F12&lt;/strong&gt;: Mostrar a definição da função ou método&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+ALT+UP&lt;/strong&gt; ou &lt;strong&gt;CTRL+ALT+DOWN&lt;/strong&gt;: Adicione um cursor acima ou abaixo da linha atual&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHIFT+ALT+I&lt;/strong&gt;: inserir um cursor no final de cada linha selecionada&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+F2&lt;/strong&gt;: Selecionar todas as ocorrências da seleção&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+SHIFT+.&lt;/strong&gt;: Ir para navegação via breadcrumbs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+ALT+LEFT&lt;/strong&gt; ou &lt;strong&gt;CTRL+ALT+RIGHT&lt;/strong&gt;: Mover o editor em grupos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHIFT+ALT+0&lt;/strong&gt;: Alternar o layout dos grupos em vertical e horizontal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALT+Z&lt;/strong&gt;: Alternar entre quebra de linha&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+KM&lt;/strong&gt;: Change a linguagem do arquivo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+B&lt;/strong&gt;: Mostrar/esconder a barra lateral&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHIFT+ALT+UP&lt;/strong&gt; ou &lt;strong&gt;SHIFT+ALT+DOWN&lt;/strong&gt;: Copiar a linha pra cima ou pra baixo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+SHIFT+K&lt;/strong&gt;: Apagar linha selecione&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F2&lt;/strong&gt;: Renomear simbolo ou variável&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+KC&lt;/strong&gt;: Comparar arquivo atual com a área de download+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+SHIFT+5&lt;/strong&gt;: Terminal divisor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+K CTRL+S&lt;/strong&gt;: Mostrar atalhos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+TAB&lt;/strong&gt;: Alternar entre aba&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+L&lt;/strong&gt;: Selecionar toda linha&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+SHIFT+L&lt;/strong&gt;: Selecionar todas as ocorrências da seleção atual&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+F2&lt;/strong&gt;: Selecionar todas as ocorrências da palavra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+SHIFT+SPACE&lt;/strong&gt;: Mostrar definição dos parâmetros&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+K CTRL+X&lt;/strong&gt;: Apagar espaços em branco&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+SHIFT+H&lt;/strong&gt;: Substituir em todos os arquivos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHIFT+ALT+F&lt;/strong&gt;: Formatar todo o documento&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+K CTRL+F&lt;/strong&gt;: Formatar seleção&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+KV&lt;/strong&gt;: Abrir preview ao lado (ex. Markdown)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+,&lt;/strong&gt;: Abrir configurações do usuário&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTRL+KZ&lt;/strong&gt;: Entrar no modo Zen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sem dúvida alguma, essa é apenas a ponta do iceberg, pois existem muuuitos outros atalhos disponíveis para usar e melhorar o seu fluxo de trabalho como desenvolvedor. Caso se interesse, deixo aqui abaixo desse post alguns links de onde procurar mais informações!&lt;/p&gt;

&lt;p&gt;Espero que tenha gostado dessa postagem e que ela tenha te ajudado, de alguma forma, a encontrar o que você procurava! 💙&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Veja mais em meu &lt;a href="https://blog.ernane.dev/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;code.visualstudio.com&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf" rel="noopener noreferrer"&gt;VsCode keyboard shortcuts linux&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf" rel="noopener noreferrer"&gt;VsCode keyboard shortcuts macos&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vscode</category>
      <category>development</category>
      <category>beginners</category>
    </item>
    <item>
      <title>[pt-br] Guia rápido e prático dos principais comandos git</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Mon, 11 Apr 2022 00:02:36 +0000</pubDate>
      <link>https://dev.to/ernanej/guia-rapido-e-pratico-dos-principais-comandos-git-1mg5</link>
      <guid>https://dev.to/ernanej/guia-rapido-e-pratico-dos-principais-comandos-git-1mg5</guid>
      <description>&lt;p&gt;&lt;a href="https://pt.wikipedia.org/wiki/Git" rel="noopener noreferrer"&gt;Git&lt;/a&gt; é um sistema de controle de versão gratuito e de código aberto, originalmente criado por &lt;a href="https://en.wikipedia.org/wiki/Linus_Torvalds" rel="noopener noreferrer"&gt;Linus Torvalds&lt;/a&gt; no ano de 2005. Ao contrário de sistemas de controle de versão centralizados mais antigos, como o SVN e CVS, o Git é distribuído, pois todo desenvolvedor tem o histórico completo de seu repositório de código localmente.&lt;/p&gt;

&lt;p&gt;O Git também oferece excelente suporte para ramificação, mesclagem e reescrita do histórico do repositório, o que levou a muitos fluxos de trabalho e ferramentas inovadoras e poderosas. As solicitações pull é uma ferramenta popular que permite que as equipes colaborem em ramificações do Git e revisem com eficiência o código uns dos outros. Atualmente, o Git é o sistema de controle de versão mais utilizado no mundo e é considerado o padrão moderno para desenvolvimento de software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Certo! mas por onde eu começo? 🤔
&lt;/h2&gt;

&lt;p&gt;É simples: instale o Git na sua máquina! fácil, não é? atualmente o Git está disponível para as mais diversas plataformas e você pode encontrar como realizar esse download/instalação no seu próprio site.&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="http://git-scm.com/" rel="noopener noreferrer"&gt;Git para todas as plataformas &lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure o Git em sua máquina
&lt;/h2&gt;

&lt;p&gt;Configure informações de usuário para todos os repositórios. 👨‍💻&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primeiramente, podemos configurar o nome que você quer ligado as suas transações de commit:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"seu nome"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;De maneira análoga, o email:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"endereco-de-email"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, você já está apto a usar o git e ter suas informações vinculadas a seus commits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando Repositórios
&lt;/h2&gt;

&lt;p&gt;Inicie um novo repositório ou obtenha algum já existente.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inicia um novo repositório &lt;code&gt;local&lt;/code&gt; com um nome específico:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git init &lt;span class="s2"&gt;"nome-do-projeto"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Realiza o download de um projeto existente, bem como todo o seu histórico de versão:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone &lt;span class="s2"&gt;"url"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Realizando e revisando alterações
&lt;/h2&gt;

&lt;p&gt;Revise edições, verifique o status de arquivos e crie transação de commit 🧐&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lista todos os arquivos novos, modificados e/ou deletados para serem commitados:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Mostra diferenças nos arquivos que ainda não foram adicionadas:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Adiciona o seu estado atual para ser commitado e realiza um snapshot 📸 do arquivo:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="s2"&gt;"arquivo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Mostra a diferença entre arquivos selecionados e a suas últimas versões já 'commitadas':
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git diff &lt;span class="nt"&gt;--staged&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Desmarca o arquivo, mas preserva seu conteúdo atual:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="s2"&gt;"arquivo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Salva o último snapshot realizado no arquivo permanentemente no histórico de versão:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"mensagem descritiva do commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mudanças agrupadas
&lt;/h2&gt;

&lt;p&gt;Nomeie uma série de commits e, em seguida, combine as alterações adequadamente em uma ramificação&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lista todas as ramificações (branches) locais no repositório atual:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Cria uma nova ramificação:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git branch &lt;span class="s2"&gt;"nome-da-ramificação"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Muda para uma ramificação específica e atualiza o diretório de trabalho atual:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git checkout &lt;span class="s2"&gt;"nome-da-ramificação"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Combina o histórico de uma ramificação específica com a ramificação atual:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git merge &lt;span class="s2"&gt;"nome-de-uma-ramificação"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Exclui uma ramificação específica:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git branch &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"nome-da-ramificação"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alterações de nomenclatura
&lt;/h2&gt;

&lt;p&gt;Mude e remova os arquivos versionados&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove o arquivo do diretório atual de trabalho e seleciona o mesmo para ser removido:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="s2"&gt;"arquivo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Remove o arquivo do controle de versão, mas preserva seu estado localmente:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="s2"&gt;"arquivo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Muda o nome do arquivo e o seleciona para o commit:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="s2"&gt;"arquivo-com-nome-atual"&lt;/span&gt; &lt;span class="s2"&gt;"arquivo-com-nome-renomeado"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Evite o rastreamento não desejados
&lt;/h2&gt;

&lt;p&gt;Crie exceções para arquivos que você deseja que não sejam rastreados e adicionados ao histórico de versão do seu projeto. Para isso, se torna necessária a criação de um arquivo de texto comum na raiz do projeto de nome específico: &lt;code&gt;.gitignore&lt;/code&gt; 🕵️&lt;/p&gt;

&lt;p&gt;Este arquivo serve para suprimir o versionamento acidental de arquivos e diretórios correspondentes aos padrões especificados, como por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;build/
.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essas especificações não permitem que arquivos presentes no diretório &lt;code&gt;build&lt;/code&gt;, ou arquivos que possuem extensão &lt;code&gt;.env&lt;/code&gt; presente em &lt;strong&gt;todo o projeto&lt;/strong&gt;, sejam rastreados ou adicionados acidentalmente para o histórico de versão.&lt;/p&gt;

&lt;p&gt;Para listar os arquivos ignorados no projeto a partir dos padrões presentes no &lt;code&gt;gitignore&lt;/code&gt;, use o comando abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git ls-files &lt;span class="nt"&gt;--other&lt;/span&gt; &lt;span class="nt"&gt;--ignored&lt;/span&gt; &lt;span class="nt"&gt;--exclude-standard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Salve fragmentos de código
&lt;/h2&gt;

&lt;p&gt;Arquive, restaure e/ou exclua estágios e alterações incompletas presentes no projeto.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Armazena temporariamente as modificações de todos os arquivos já rastreados:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git stash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Aplica as alterações presentes no último stash:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git stash apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Restaura os arquivos recentes em stash:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git stash pop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Lista todos os conjuntos de alterações presentes em stash:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git stash list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Descarta os conjuntos de alterações mais recentes em stash:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git stash drop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Revise seu histórico de versão
&lt;/h2&gt;

&lt;p&gt;Navegue, valide e inspecione a evolução dos arquivos presentes no projeto.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lista todo o histórico de versões para o branch atual:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Lista o histórico de versões para um arquivo, incluindo mudanças em seu nome:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--follow&lt;/span&gt; &lt;span class="s2"&gt;"arquivo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Mostra a diferença de conteúdo entre duas ramificações:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git diff &lt;span class="s2"&gt;"primeira-ramificação"&lt;/span&gt;...&lt;span class="s2"&gt;"segunda-ramificação"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Retorna mudanças de metadata e conteúdo para o commit especificado:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git show &lt;span class="s2"&gt;"commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reabra seus commits
&lt;/h2&gt;

&lt;p&gt;Desfaça enganos cometidos e crie um histórico substituto &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Volta o histórico de versão ao estado do commit passado, mas mantendo as alterações no espaço de trabalho:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="s2"&gt;"commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Retorna ao estado do commit passado, mas desfazendo todas as alterações e commits realizados após ele:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; &lt;span class="s2"&gt;"commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Sincronize e salve as suas alterações 
Baixa todo o histórico de um marcador de repositório:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git fetch &lt;span class="s2"&gt;"marcador"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Combina o marcador da ramificação passada na ramificação local:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git merge &lt;span class="s2"&gt;"marcador"&lt;/span&gt;/&lt;span class="s2"&gt;"branch"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Envia todos os commits da ramificação local para a sua versão remota:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git push &lt;span class="s2"&gt;"alias"&lt;/span&gt; &lt;span class="s2"&gt;"branch"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Baixa o histórico presente no repositório remoto e incorpora as mudanças no repositório local:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ufaa! 😅&lt;/p&gt;

&lt;p&gt;Sem dúvidas você está com mais do que o necessário para versionar o seu código de maneira correta e segura. O bom de se utilizar do git é que, como foi citado anteriormente, ele é globalmente utilizado, o que possibilita aplicarmos esse conhecimento adquirido em qualquer plataforma que disfrute de seus serviços, como o &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, &lt;a href="https://gitlab.com/" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt;, etc.&lt;/p&gt;

&lt;p&gt;Pode ter certeza que existem muitos outros comandos presentes no git que poderão te ajudar no dia a dia, mas essa listagem de comandos acima consegue te dar um ferramental muito forte para começar. Contudo, como de costume, deixo abaixo algumas referências que você poderá utilizar para desbravar esse mundo do versionamento de código.&lt;/p&gt;

&lt;p&gt;Espero que tenha gostado dessa postagem e que ela tenha te ajudado de alguma forma a encontrar o que você procurava! 💙&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Veja mais em meu &lt;a href="https://blog.ernane.dev/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://git-scm.com/docs/" rel="noopener noreferrer"&gt;Documentação do Git em seu site oficial&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://training.github.com/downloads/pt_BR/github-git-cheat-sheet.pdf" rel="noopener noreferrer"&gt;Folha de dicas de Git proporcionado pelo GitHub&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>gitlab</category>
      <category>github</category>
      <category>codequality</category>
    </item>
    <item>
      <title>[pt-br] Netlify e Google Domains: como configurá-los corretamente.</title>
      <dc:creator>Ernane Ferreira</dc:creator>
      <pubDate>Mon, 07 Mar 2022 01:34:53 +0000</pubDate>
      <link>https://dev.to/ernanej/netlify-e-google-domains-como-configura-los-corretamente-eja</link>
      <guid>https://dev.to/ernanej/netlify-e-google-domains-como-configura-los-corretamente-eja</guid>
      <description>&lt;p&gt;Recentemente, para implementação do meu &lt;a href="https://ernane.dev/" rel="noopener noreferrer"&gt;site pessoal&lt;/a&gt;, adquiri o meu próprio domínio. Sempre quis ter um próprio e optei por comprar via &lt;a href="https://domains.google/" rel="noopener noreferrer"&gt;domínios do Google&lt;/a&gt;. O processo de compra é relativamente simples, só são necessários os dados do cartão de crédito e endereço. Após isso, já estava com o meu domínio registrado, mas as configurações não são tão simples quanto o registro... 🧐&lt;/p&gt;

&lt;p&gt;Decidi hospedar o meu site no &lt;a href="https://www.netlify.com/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt;, mas as configurações para outra empresa não devem ser tão diferentes. Abaixo mostrarei os passos para realizar as configurações do novo domínio adquirido com o site já hospedado.&lt;/p&gt;

&lt;p&gt;Para ficar mais simples de compreender, as etapas foram divididas em duas: a primeira para a captura dos servidores de nomes no netlify e a outra para a aplicação deles no painel do google domains. Boa leitura! 📒&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuração no Netlify
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;No console do netlify, acesse seu site e vá para a sessão de &lt;strong&gt;Configurações de domínio&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt; Em seguida, clique em &lt;strong&gt;Adicionar domínio personalizado&lt;/strong&gt;, um provável botão verde 😝;&lt;/li&gt;
&lt;li&gt;Após isso, provavelmente o seu domínio terá um banner inicializando com a opção 2 sendo &lt;strong&gt;Configurar seu domínio personalizado&lt;/strong&gt;. Quando aparecer, clique nele;&lt;/li&gt;
&lt;li&gt;Agora você será solicitado a fornecer o domínio que comprou (no meu caso, foi &lt;a href="https://ernane.dev/" rel="noopener noreferrer"&gt;ernane.dev&lt;/a&gt;). Se você for o proprietário do domínio, o site solicitará que você valide que realmente é o dono, mas basta clicar em verificar. Um bom ponto a se levar em conta é que o próprio Netlify pode fornecer um domínio à você;&lt;/li&gt;
&lt;li&gt;Depois de todos esses passos, você será redirecionado para as configurações do seu domínio e verá um aviso solicitando que você configure seu DNS:  Clique em &lt;strong&gt;Opções&lt;/strong&gt;  ➡  &lt;strong&gt;Configurar DNS Netlify&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;Adicione o domínio no campo solicitado - Provavelmente o Netlify solicitará que você verifique novamente seu domínio;&lt;/li&gt;
&lt;li&gt;Adicione os registros DNS - Os registros DNS para seus sites Netlify serão configurados automaticamente. Você poderá pular essa parte, a menos que tenha um e-mail configurado com seu domínio;&lt;/li&gt;
&lt;li&gt;Ative o DNS Netlify - O Nelify lhe dará nomes de seus provedores de nome. Mantenha-os abertos ou salve-os e dirija-se ao seu provedor de nome de domínio.&lt;/li&gt;
&lt;/ol&gt;

&lt;center&gt;Prontinho! Com o Netlify já está tudo okay. 😄&lt;/center&gt;

&lt;h2&gt;
  
  
  Domínios do Google
&lt;/h2&gt;

&lt;p&gt;Aqui será um pouco mais simples! 😁&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No painel de configurações do seu domínio no Google Domains, vá para a seção Domain Name System - &lt;strong&gt;DNS&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Na seção &lt;strong&gt;NameServers&lt;/strong&gt;, selecione a opção &lt;strong&gt;Usar nameservers personalizados&lt;/strong&gt;. Para dominios do google, antes de adicionar os meus próprios, tornou-se necessário desabilitar o &lt;a href="https://cloud.google.com/dns/docs/dnssec" rel="noopener noreferrer"&gt;DNSSEC&lt;/a&gt; (Domain Name System Security Extensions), um recurso do (DNS) que autentica respostas à pesquisas de nome de domínio;&lt;/li&gt;
&lt;li&gt;Em seguida, adicione os servidores de nomes que foram fornecidos pelo Netlify nos passos anteriores aos campos disponíveis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;E fim! seguindo todos os passos, seu domínio já estará configurado. Você verá que os domínios do google poderão recomendar uma espera de aproximadamente 48 horas para que as alterações sejam realizadas, mas comigo foi relativamente rápido. Após cerca de 15 a 30 minutos... Tcharann! 🎉 lá estava o meu novo site com o domínio configurado corretamente.&lt;/p&gt;

&lt;p&gt;Espero que tenha gostado dessa postagem e te ajudado, de alguma forma, a encontrar o que você procurava! 💙&lt;/p&gt;

&lt;h2&gt;
  
  
  Links úteis:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.netlify.com/domains-https/custom-domains/" rel="noopener noreferrer"&gt;Documentação do Netlify sobre domínios personalizados&lt;/a&gt; (en); &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com/domains/docs/register-domain" rel="noopener noreferrer"&gt;Documentação do Google Domains sobre registro de novos domínios&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com/dns/docs/dnssec" rel="noopener noreferrer"&gt;Visão geral das segurança de segurança de DNS (DNSSE)&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>netlify</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
