<?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>Forem: Ahmed Nadar</title>
    <description>The latest articles on Forem by Ahmed Nadar (@ahmednadar).</description>
    <link>https://forem.com/ahmednadar</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%2F359115%2Fe8e609fc-ad4b-4815-816c-80cb57896cfe.jpeg</url>
      <title>Forem: Ahmed Nadar</title>
      <link>https://forem.com/ahmednadar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ahmednadar"/>
    <language>en</language>
    <item>
      <title>Normalization in Rails 7.1 era</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Tue, 21 May 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/ahmednadar/normalization-in-rails-71-era-33n6</link>
      <guid>https://forem.com/ahmednadar/normalization-in-rails-71-era-33n6</guid>
      <description>&lt;h3&gt;
  
  
  Before Rails 7.1
&lt;/h3&gt;

&lt;p&gt;Once upon a time, way long before the &lt;strong&gt;Rails 7.1 era&lt;/strong&gt;, a smart Rails developer (like yourself) needed to ensure user email addresses were properly normalized (&lt;a href="https://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html#method-i-sanitize"&gt;sanitized&lt;/a&gt; and formatted correctly). Back then, they used clever techniques such as callbacks like &lt;a href="https://edgeapi.rubyonrails.org/classes/ActiveRecord/Callbacks/ClassMethods.html#method-i-before_save"&gt;before_save&lt;/a&gt; and &lt;a href="https://edgeapi.rubyonrails.org/classes/ActiveModel/Validations/Callbacks/ClassMethods.html#method-i-before_validation"&gt;before_validation&lt;/a&gt;, attribute setters, or even the &lt;a href="https://github.com/eet-nu/normalize"&gt;normalize&lt;/a&gt; gem to get the job done. Here are some of those old tricks and tips on how they used to do it.&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;# normalize with before_save callback&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;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;before_save&lt;/span&gt; &lt;span class="ss"&gt;:sanitize_email&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sanitize_email&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&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;# normalize with before_validation callback&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;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;before_validation&lt;/span&gt; &lt;span class="ss"&gt;:sanitize_email&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sanitize_email&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&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;# override the setter from ActiveRecord&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;ApplicationRecord&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;&lt;span class="p"&gt;)&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;# Don't like callbacks? Use the normalize gem in `app/normalizers`&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailNormalizer&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&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;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;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;normalize&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="no"&gt;EmailNormalizer&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After Rails 7.1
&lt;/h3&gt;

&lt;p&gt;As time passed, the Rails community reached the &lt;strong&gt;Rails 7.1 era&lt;/strong&gt;. A group of those smart Rails developers (maybe it's you) gathered around the Rails core team and agreed on a better way to normalize attributes. They came up with a nifty idea.&lt;/p&gt;

&lt;p&gt;Imagine having a &lt;a href="https://edgeapi.rubyonrails.org/classes/ActiveRecord/Normalization/ClassMethods.html"&gt;ClassMethod&lt;/a&gt; &lt;code&gt;normalizes&lt;/code&gt; that comes with a set of rules, such as converting all email addresses to lowercase, removing leading/trailing whitespace, or enforcing a specific format before they are saved to the database. This "&lt;a href="https://edgeapi.rubyonrails.org/classes/ActiveRecord/Normalization.html"&gt;Normalization&lt;/a&gt;" class reduces data redundancy and minimizes inconsistencies. Also, it organizes data in a structured and consistent way, making it easier to query, update, and maintain.&lt;/p&gt;

&lt;p&gt;The Rails core team wanted to make it easy for today's and future Rails developers by providing a simple &lt;a href="https://github.com/rails/rails/pull/43945"&gt;API&lt;/a&gt; for model attributes. All developers need to do is pass the attribute's name. Here is how they demonstrated their solution. Pow 💥&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;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;normalizes&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;normalizes&lt;/span&gt; &lt;span class="ss"&gt;:phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;phone&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="s2"&gt;"^0-9"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;delete_prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&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;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s2"&gt;" CRUISE-CONTROL@EXAMPLE.COM&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&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;email&lt;/span&gt;                  &lt;span class="c1"&gt;# =&amp;gt; "cruise-control@example.com"&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;find_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;CRUISE-CONTROL@EXAMPLE.COM "&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;email&lt;/span&gt;                  &lt;span class="c1"&gt;# =&amp;gt; "cruise-control@example.com"&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;email_before_type_cast&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "cruise-control@example.com"&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="ss"&gt;email: &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;CRUISE-CONTROL@EXAMPLE.COM "&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;         &lt;span class="c1"&gt;# =&amp;gt; 1&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="s2"&gt;"email = ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;CRUISE-CONTROL@EXAMPLE.COM "&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 0&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;exists?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;CRUISE-CONTROL@EXAMPLE.COM "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;# =&amp;gt; true&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;exists?&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"email = ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;CRUISE-CONTROL@EXAMPLE.COM "&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; false&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;normalize_value_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"+1 (555) 867-5309"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "5558675309"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And Rails developers &lt;a href="https://israilsdead.com/"&gt;live&lt;/a&gt; happily ever after Rails 7.1 period.&lt;br&gt;
The end.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Refactoring Rails Helpers from static to dynamic rendering</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Tue, 12 Mar 2024 13:00:00 +0000</pubDate>
      <link>https://forem.com/ahmednadar/refactoring-rails-helpers-from-static-to-dynamic-rendering-2f85</link>
      <guid>https://forem.com/ahmednadar/refactoring-rails-helpers-from-static-to-dynamic-rendering-2f85</guid>
      <description>&lt;p&gt;Writing code is a journey of continuous improvement, learning, adaptation, and, yes, refactoring. As our applications grow and evolve, we often find ourselves revisiting and rethinking our code to make it more maintainable, scalable, and flexible.&lt;/p&gt;

&lt;p&gt;Today, I want to share with you the process of refactoring a helper in a Rails application to dynamically render components. This adventure is filled with twists, turns, and a sprinkle of humour.&lt;/p&gt;

&lt;p&gt;When I was explaining this refactoring process to a friend, I realized that it had all the elements of a classic fairy 🧚🏼 tale: a humble beginning, a villain to overcome, a twist in the plot, and a happy ending. So, today I'm trying a new style of writing, a fairy tale, to make it more engaging and fun. So, let's dive in.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chapter One: In the land of static helpers
&lt;/h4&gt;

&lt;p&gt;My story begins with a humble helper, &lt;code&gt;RapidRailsUI::ViewHelper&lt;/code&gt;, designed to render components in a Rails application. Like any good story, I start small and simple. Here's how it looked initially:&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;module&lt;/span&gt; &lt;span class="nn"&gt;RapidRailsUI&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ViewHelper&lt;/span&gt;
    &lt;span class="no"&gt;RAPIDRAILSUI_COMPONENTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;button: &lt;/span&gt;&lt;span class="s2"&gt;"RapidRailsUI::HeadlessButton"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;icon: &lt;/span&gt;&lt;span class="s2"&gt;"RapidRailsUI::IconComponent"&lt;/span&gt;
      &lt;span class="c1"&gt;# Add more components as needed&lt;/span&gt;
    &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

    &lt;span class="no"&gt;RAPIDRAILSUI_COMPONENTS&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="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;define_method&lt;/span&gt; &lt;span class="ss"&gt;:"rui_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="ss"&gt;"&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;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constantize&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helper served its purpose well 👌🏽, it create a component name such as &lt;code&gt;rui_buddon&lt;/code&gt; but as the application grew, so did the number of components. And with each new component, I found myself updating the &lt;code&gt;RAPIDRAILSUI_COMPONENTS&lt;/code&gt; hash. It quickly became apparent that this wasn't the most scalable solution&lt;/p&gt;

&lt;h4&gt;
  
  
  Chapter Two: A small step for a developer, a giant leap for helper kind
&lt;/h4&gt;

&lt;p&gt;To make the helper more dynamic and easier to maintain, I started with a small change. Instead of hardcoding the component names and classes in the &lt;code&gt;RAPIDRAILSUI_COMPONENTS&lt;/code&gt; hash, I used a symbol array to store the component names. This way, adding new components became a breeze:&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;module&lt;/span&gt; &lt;span class="nn"&gt;RapidRailsUI&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ViewHelper&lt;/span&gt;
    &lt;span class="no"&gt;RAPIDRAILSUI_COMPONENTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%i[button icon]&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

    &lt;span class="no"&gt;RAPIDRAILSUI_COMPONENTS&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="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;define_method&lt;/span&gt; &lt;span class="ss"&gt;:"rui_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="ss"&gt;"&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;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;component_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"RapidRailsUI::&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;classify&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Component"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constantize&lt;/span&gt;
        &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="n"&gt;component_class&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this approach still had its limitations. The &lt;code&gt;RAPIDRAILSUI_COMPONENTS&lt;/code&gt; array still required manual updates for each new component. I needed a more dynamic and flexible solution.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chapter Three: The mystery of the missing dynamism
&lt;/h4&gt;

&lt;p&gt;To address the scalability issue, I embarked on a journey to refactor the view helper to dynamically resolve component names based on the method called. This way, there would be no need to update the helper every time a new component was added. Here's the first iteration of the refactored helper:&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;module&lt;/span&gt; &lt;span class="nn"&gt;RapidRailsUI&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ViewHelper&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rui_"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;component_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rui_"&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="nf"&gt;classify&lt;/span&gt;
        &lt;span class="n"&gt;component_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"RapidRailsUI::&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;component_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Component"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_constantize&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;component_class&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="n"&gt;component_class&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&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;super&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;respond_to_missing?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include_private&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rui_"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;super&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this refactor, the &lt;code&gt;ViewHelper&lt;/code&gt; became more dynamic and easier to maintain. However, every fairy tale has its villain, and ours was about to make an appearance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chapter Four: The case of the uncooperative classify
&lt;/h4&gt;

&lt;p&gt;As I happily refactored the components, I faced an unexpected issue with &lt;code&gt;TabsComponent&lt;/code&gt;. The method &lt;code&gt;rui_tabs&lt;/code&gt; was resolving to &lt;code&gt;RapidRailsUI::TabComponent&lt;/code&gt; instead of &lt;code&gt;RapidRailsUI::TabsComponent&lt;/code&gt;. It turns out that Rails' &lt;code&gt;classify&lt;/code&gt; method, designed for singularizing model names, was not playing nice with the component names.&lt;/p&gt;

&lt;p&gt;To defeat this villain, I introduced a special case in the view helper to handle the pluralization of component names that don't follow the standard Rails convention:&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;module&lt;/span&gt; &lt;span class="nn"&gt;RapidRailsUI&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ViewHelper&lt;/span&gt;
    &lt;span class="no"&gt;SPECIAL_PLURALIZATIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'tabs'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Tabs'&lt;/span&gt;
    &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rui_"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;component_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rui_"&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="n"&gt;component_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SPECIAL_PLURALIZATIONS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;component_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;component_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;classify&lt;/span&gt;
        &lt;span class="n"&gt;component_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"RapidRailsUI::&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;component_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Component"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_constantize&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;component_class&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="n"&gt;component_class&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&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;super&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;respond_to_missing?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include_private&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rui_"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;super&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this final tweak, &lt;code&gt;ViewHelper&lt;/code&gt; became both dynamic and accommodating to the special cases. I could now add new components without worrying about updating the helper or dealing with naming conventions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Epilogue: the dawn of a new era in helper land
&lt;/h4&gt;

&lt;p&gt;In the end, the refactoring journey led me to a view helper that was scalable, flexible, and a joy to work with. I no longer had to manually update the helper for each new component, and I could easily handle exceptions to naming conventions.&lt;/p&gt;

&lt;p&gt;So, I hope this tale of refactoring has inspired you to embrace the dynamic nature of Ruby and Rails. By leveraging the power of metaprogramming, you can create helpers that are more maintainable, scalable, and delightful to work with.&lt;br&gt;
And they all coded happily ever after. The end.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Methods Explained
&lt;/h4&gt;

&lt;p&gt;In this refactoring journey, I've used several Ruby and Rails methods to achieve a dynamic and scalable view helper. Let's dive into the details of these key methods:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;classify&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it does:&lt;/strong&gt; Converts a string to a class name. For example, &lt;code&gt;"button".classify&lt;/code&gt; becomes &lt;code&gt;"Button"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it's used:&lt;/strong&gt; In the refactor, I used &lt;code&gt;classify&lt;/code&gt; to dynamically convert component names from strings to class names.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Further reading:&lt;/strong&gt; &lt;a href="https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-classify"&gt;ActiveSupport::Inflector#classify&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;safe_constantize&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it does:&lt;/strong&gt; Tries to find a constant with the name specified in the string. If the constant doesn't exist, it returns &lt;code&gt;nil&lt;/code&gt; instead of raising a &lt;code&gt;NameError&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it's used:&lt;/strong&gt; I used &lt;code&gt;safe_constantize&lt;/code&gt; to safely resolve component class names without risking a crash if the class doesn't exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Further reading:&lt;/strong&gt; &lt;a href="https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-safe_constantize"&gt;ActiveSupport::Inflector#safe_constantize&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;method_missing&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it does:&lt;/strong&gt; Called when a method is invoked on an object but is not defined for that object. It's a powerful tool for metaprogramming.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it's used:&lt;/strong&gt; I leveraged &lt;code&gt;method_missing&lt;/code&gt; to dynamically handle method calls for rendering components based on their names starts with &lt;code&gt;rui_&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Further reading:&lt;/strong&gt; &lt;a href="https://ruby-doc.org/core-2.7.0/BasicObject.html#method-i-method_missing"&gt;Ruby's &lt;code&gt;method_missing&lt;/code&gt; documentation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;respond_to_missing?&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it does:&lt;/strong&gt; Used in conjunction with &lt;code&gt;method_missing&lt;/code&gt; to ensure that Ruby's &lt;code&gt;respond_to?&lt;/code&gt; method works correctly for dynamically handled methods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it's used:&lt;/strong&gt; I implemented &lt;code&gt;respond_to_missing?&lt;/code&gt; to accurately report whether the view helper can respond to dynamically generated methods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Further reading:&lt;/strong&gt; &lt;a href="https://ruby-doc.org/core-2.7.0/Object.html#method-i-respond_to_missing-3F"&gt;Ruby's &lt;code&gt;respond_to_missing?&lt;/code&gt; documentation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding these methods, you can harness the power of Ruby and Rails to create more dynamic and flexible code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Refactoring view helpers in Rails can be a rewarding adventure. By embracing the dynamic nature of Ruby and Rails, you can transform your helpers into powerful, scalable tools that make your codebase more maintainable and your development experience more enjoyable.&lt;/p&gt;

&lt;p&gt;So, the next time you find yourself staring at a helper that needs a little love, remember this tale of refactoring and embark on your own journey of improvement. Your codebase will thank you, and you'll emerge as the hero of your own story.&lt;/p&gt;

&lt;p&gt;Happy coding, and may your helpers be ever dynamic and delightful! 🚀&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>refactorit</category>
    </item>
    <item>
      <title>Simplifying Polymorphic Associations with Rails ActiveRecord::DelegatedType</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Thu, 11 Jan 2024 17:07:45 +0000</pubDate>
      <link>https://forem.com/ahmednadar/simplifying-polymorphic-associations-with-rails-activerecorddelegatedtype-59ji</link>
      <guid>https://forem.com/ahmednadar/simplifying-polymorphic-associations-with-rails-activerecorddelegatedtype-59ji</guid>
      <description>&lt;p&gt;Hey Rails dev! Ever struggled with handling different types of data in your Rails applications? Well, &lt;code&gt;ActiveRecord::DelegatedType&lt;/code&gt; is here to make your life easier. In this guide, I'll walk through how you can use &lt;code&gt;DelegatedType&lt;/code&gt; to manage diverse data relationships in a more organized way. It's like having a neat filing system for your database tables. So, let's dive in and explore how &lt;code&gt;DelegatedType&lt;/code&gt; can help you keep your Rails projects well-structured and easy to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  What!
&lt;/h2&gt;

&lt;p&gt;Let's introduce ActiveRecord's &lt;code&gt;DelegatedType&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;It is a Rails pattern for managing polymorphic associations in a more structured and efficient way. Think of it as a way to store a superclass that can be subclassed using delegation instead of inheritance. It's like having a Swiss Army knife in your Rails ActiveRecord toolkit!&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use &lt;code&gt;DelegatedType&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Leverage &lt;code&gt;DelegatedType&lt;/code&gt; when you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage objects sharing common features and behaviours but requiring distinct handling.&lt;/li&gt;
&lt;li&gt;Simplify complex relationships under a unified interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How: the core idea
&lt;/h2&gt;

&lt;p&gt;At its core, &lt;code&gt;DelegatedType&lt;/code&gt; simplifies the handling of models that can represent multiple types of related data without the complexity of Single Table Inheritance (STI).&lt;/p&gt;

&lt;p&gt;For example, In a blog application with posts, comments, and authors, &lt;code&gt;ActiveRecord::DelegatedType&lt;/code&gt; is very handy when you want to have a single model that can represent different types of related data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why, embrace &lt;code&gt;DelegatedType&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Here’s why &lt;code&gt;DelegatedType&lt;/code&gt; can be your best friend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplifies Polymorphic Relationships:&lt;/strong&gt; Manages different types of data under a unified interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoids STI Drawbacks:&lt;/strong&gt; Prevents cluttering a single table with columns relevant to only specific types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhances Code Readability:&lt;/strong&gt; Clear separation of concerns, making it easier to understand and maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example scenario, Blog application
&lt;/h2&gt;

&lt;p&gt;Consider a blog application with posts, comments, and authors, where posts and comments share common features but also have unique attributes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-Step Implementation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Define a Common Interface
&lt;/h4&gt;

&lt;p&gt;Create a module, say &lt;code&gt;Publishable&lt;/code&gt;, to encapsulate shared logic and behaviour.&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;# app/models/concerns/publishable.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Publishable&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concern&lt;/span&gt;

  &lt;span class="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;has_one&lt;/span&gt; &lt;span class="ss"&gt;:publication&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: :publishable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;touch: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="c1"&gt;# Other shared logic...&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;h4&gt;
  
  
  2. Create a Superclass Model
&lt;/h4&gt;

&lt;p&gt;Define a &lt;code&gt;Publication&lt;/code&gt; model to act as a superclass using &lt;code&gt;delegated_type&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;# app/models/publication.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Publication&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;delegated_type&lt;/span&gt; &lt;span class="ss"&gt;:publishable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;types: &lt;/span&gt;&lt;span class="sx"&gt;%w[ Post Comment ]&lt;/span&gt;

  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;
  &lt;span class="c1"&gt;# Common logic like publication date and author references&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Define Subclasses
&lt;/h4&gt;

&lt;p&gt;Implement &lt;code&gt;Post&lt;/code&gt; and &lt;code&gt;Comment&lt;/code&gt; models, including the &lt;code&gt;Publishable&lt;/code&gt; module.&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;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Publishable&lt;/span&gt;
  &lt;span class="c1"&gt;# Attributes specific to posts&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Publishable&lt;/span&gt;
  &lt;span class="c1"&gt;# Attributes specific to comments&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Handling Records
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;Publications&lt;/code&gt; that are either &lt;code&gt;Posts&lt;/code&gt; or &lt;code&gt;Comments&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;# Creating a new post&lt;/span&gt;
&lt;span class="no"&gt;Publication&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;publishable: &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;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s1"&gt;'My First Post'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="n"&gt;some_author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Creating a new comment&lt;/span&gt;
&lt;span class="no"&gt;Publication&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;publishable: &lt;/span&gt;&lt;span class="no"&gt;Comment&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;content: &lt;/span&gt;&lt;span class="s1"&gt;'Great post!'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="n"&gt;another_author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or generate &lt;a href="https://github.com/AhmedNadar/delegate_blog/blob/main/db/seeds.rb"&gt;seed data&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Nested Attributes
&lt;/h3&gt;

&lt;p&gt;You can use nested attributes to handle form submissions for both posts and comments through the &lt;code&gt;Publication&lt;/code&gt; model.&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;Publication&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;accepts_nested_attributes_for&lt;/span&gt; &lt;span class="ss"&gt;:publishable&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;h3&gt;
  
  
  Delegating Methods
&lt;/h3&gt;

&lt;p&gt;Delegating methods to the subclasses can streamline accessing subclass-specific attributes.&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;Publication&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
    &lt;span class="c1"&gt;# Delegating a method (e.g., title for Post, content for Comment) to the publishable object&lt;/span&gt;
    &lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: :publishable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;allow_nil: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Querying
&lt;/h3&gt;

&lt;p&gt;Querying is straightforward; you can fetch either all publications, just posts, or just comments.&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;# Fetch all publications&lt;/span&gt;
&lt;span class="n"&gt;publications&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Publication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;

&lt;span class="c1"&gt;# Fetch all posts&lt;/span&gt;
&lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Publication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;posts&lt;/span&gt;

&lt;span class="c1"&gt;# Fetch all comments&lt;/span&gt;
&lt;span class="n"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Publication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;comments&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📋 Conclusion
&lt;/h2&gt;

&lt;p&gt;As we have seen &lt;code&gt;ActiveRecord::DelegatedType&lt;/code&gt; offers a robust and flexible way to handle polymorphic associations. You can effectively implement and leverage this pattern, enhancing the structure and maintainability of your Rails applications. &lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Demo repo
&lt;/h2&gt;

&lt;p&gt;Now, curious to see &lt;code&gt;ActiveRecord::DelegatedType&lt;/code&gt; in action? I've created a demo Rails app that showcases the usage of &lt;code&gt;DelegatedType&lt;/code&gt; for managing polymorphic associations, along with advanced use cases. In addition, the app includes views to demonstrate the display of all posts and publications, making it a handy tool for app admins who need to oversee various data objects at once. You can check out the demo and explore the code on &lt;a href="https://github.com/AhmedNadar/delegate_blog"&gt;GitHub&lt;/a&gt;. It's a great way to get a hands-on understanding of how &lt;code&gt;DelegatedType&lt;/code&gt; can streamline your data management tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Further Learning
&lt;/h2&gt;

&lt;p&gt;For more in-depth examples and advanced use cases, check &lt;a href="https://edgeapi.rubyonrails.org/classes/ActiveRecord/DelegatedType.html"&gt;Rails DelegatedType API documentation&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Composing '99 Bottles of Beer' with Ruby's OOP Harmony'</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Tue, 07 Nov 2023 20:27:57 +0000</pubDate>
      <link>https://forem.com/ahmednadar/composing-99-bottles-of-beer-with-rubys-oop-harmony-2871</link>
      <guid>https://forem.com/ahmednadar/composing-99-bottles-of-beer-with-rubys-oop-harmony-2871</guid>
      <description>&lt;h2&gt;
  
  
  🌟 Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome back 😀! In a &lt;a href="https://ahmednadar.hashnode.dev/a-ruby-serenade-for-99-bottles-of-beer"&gt;previous post&lt;/a&gt;, I tackled the classic "&lt;a href="https://sandimetz.com/99bottles"&gt;99 Bottles of Beer&lt;/a&gt;" problem using a procedural approach, leveraging &lt;a href="https://ruby-doc.org/3.2.2/syntax/control_expressions_rdoc.html#label-case+Expression"&gt;Ruby's case expression&lt;/a&gt; to create a straightforward solution. Today, I revisit this catchy tune with a fresh perspective: Object-Oriented Programming (OOP). Thanks to insights from &lt;a href="https://twitter.com/sandimetz"&gt;Sandi Metz&lt;/a&gt;, &lt;a href="https://twitter.com/kytrinyx"&gt;Katrina Owen&lt;/a&gt;, and my friend Koichi.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤖 Understanding Object-Oriented Programming in Our Digital Narrative
&lt;/h2&gt;

&lt;p&gt;As we prepare to revisit the classic '99 Bottles of Beer' with an object-oriented approach, it's essential to grasp the fundamental concepts of &lt;a href="https://en.wikipedia.org/wiki/Object-oriented_programming"&gt;Object-Oriented Programming (OOP)&lt;/a&gt; that we'll be employing:&lt;/p&gt;

&lt;p&gt;-&lt;strong&gt;Encapsulation&lt;/strong&gt;: This is about bundling data with the methods that operate on it, encapsulating behaviour with the data it manipulates.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inheritance&lt;/strong&gt;: A mechanism for creating new classes from existing ones, this enhances code reusability and establishes a natural hierarchy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Polymorphism&lt;/strong&gt;: It allows entities to take on more than one form, enabling a single function to handle different types of objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Abstraction&lt;/strong&gt;: By hiding the complex reality behind simpler interfaces, we expose only the necessary components, making our code more approachable and easier to understand.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Embracing these principles doesn't merely organize our code; it's akin to composing a digital story where each object plays a part, modelled after real-world behaviours and interactions. In the context of our '99 Bottles of Beer' rendition, we're not just coding – we're crafting a symphony of objects that each carry their tune, harmonizing to create a cohesive and scalable application.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎼 The SOLID Principles Concerto
&lt;/h2&gt;

&lt;p&gt;In OOP, SOLID principles guide our design towards harmony:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Single-responsibility_principle"&gt;Single Responsibility Principle (SRP)&lt;/a&gt; - A class should have one, and only one, reason to change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle"&gt;Open/Closed Principle (OCP)&lt;/a&gt; - Classes should be open for extension but closed for modification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle"&gt;Liskov Substitution Principle (LSP)&lt;/a&gt; - Subtypes must be substitutable for their base types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Interface_segregation_principle"&gt;Interface Segregation Principle (ISP)&lt;/a&gt; - No client should be forced to depend on methods it does not use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle"&gt;Dependency Inversion Principle (DIP)&lt;/a&gt; - Depend on abstractions, not on concretions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's see how these principles are integrated into our '99 Bottles' code.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Step-by-Step OOP Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Act I: Crafting the Bottle Class with SRP
&lt;/h3&gt;

&lt;p&gt;First, we encapsulate the idea of a bottle into its own class, which knows how to represent itself and its actions. In this &lt;code&gt;Bottle&lt;/code&gt; class, we have defined methods to represent the bottle textually (&lt;code&gt;to_s&lt;/code&gt;), the action to take (&lt;code&gt;action&lt;/code&gt;), and to get the next bottle object (&lt;code&gt;next&lt;/code&gt;). The &lt;code&gt;attr_reader&lt;/code&gt; provides a way to read the &lt;code&gt;quantity&lt;/code&gt; attribute outside the class. Create &lt;code&gt;bottle.rb&lt;/code&gt; file.&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;# This file contains the Bottle class which represents a bottle in the song.&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bottle&lt;/span&gt;
    &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Define a method to represent the bottle count in a verse.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;
        &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="s2"&gt;"no more bottles"&lt;/span&gt;
        &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="s2"&gt;"1 bottle"&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bottles"&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;# Method to print the action part of the verse.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;action&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;positive?&lt;/span&gt;
        &lt;span class="s2"&gt;"Take one down and pass it around"&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="s2"&gt;"Go to the store and buy some more"&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;# Method to get the next bottle object.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;
        &lt;span class="no"&gt;Bottle&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="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;positive?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;quantity&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="mi"&gt;99&lt;/span&gt;&lt;span class="p"&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;&lt;em&gt;Why OOP?&lt;/em&gt; Encapsulation ensures the bottle's behaviour is closely tied to its data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Act II: Building the BeerWall Class and OCP
&lt;/h3&gt;

&lt;p&gt;Now, let's construct our wall. The &lt;code&gt;BeerWall&lt;/code&gt; class interacts with bottle objects in a high-level way. We don't need to know how each bottle composes its verse; we only need to know that it can do so. The &lt;code&gt;sing&lt;/code&gt; method prints all the verses of the song by iterating over each bottle and printing its verse. The &lt;code&gt;verse&lt;/code&gt; method is a clear application of &lt;strong&gt;SRP&lt;/strong&gt; as it has a single responsibility: to return the verse text for a given number of bottles. The &lt;code&gt;print_verse&lt;/code&gt; method supports these principles internally, ensuring that the public interface remains unchanged while the class's internal workings can evolve as needed. Create &lt;code&gt;beer_wall.rb&lt;/code&gt; file.&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;# This class is responsible for printing the entire song.&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s2"&gt;"bottle"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BeerWall&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@bottles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bottles&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Prints a single verse for a given bottle.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bottle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Bottle&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="n"&gt;number&lt;/span&gt;&lt;span class="p"&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;bottle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer on the wall, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;bottle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&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;bottle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;action&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;bottle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer on the wall.&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;# Prints the entire song.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sing&lt;/span&gt;
        &lt;span class="vi"&gt;@bottles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;print_verse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Bottle&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="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kp"&gt;private&lt;/span&gt;

    &lt;span class="c1"&gt;# Prints a single verse for a given bottle.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_verse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bottle&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;bottle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer on the wall, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;bottle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer."&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;bottle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;action&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;bottle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer on the wall.&lt;/span&gt;&lt;span class="se"&gt;\n\n&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;&lt;em&gt;Why OOP?&lt;/em&gt; The &lt;code&gt;BeerWall&lt;/code&gt; class showcases abstraction by allowing us to interact with bottle objects in a high-level way.&lt;/p&gt;

&lt;p&gt;While it is optionally, a driver script or a file that uses these classes to perform the desired actions. Create &lt;code&gt;ruby_sing.rb&lt;/code&gt; file.&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_relative&lt;/span&gt; &lt;span class="s2"&gt;"beer_wall"&lt;/span&gt;

&lt;span class="no"&gt;BeerWall&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="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;ruby ruby_sing.rb&lt;/code&gt; to see the &lt;a href="https://github.com/AhmedNadar/99BottlesChallenge/blob/main/result.md"&gt;desired output&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Act III: Respecting LSP with Inheritance
&lt;/h3&gt;

&lt;p&gt;Imagine we introduce a &lt;code&gt;BottleVariant&lt;/code&gt; class for a special kind of bottle. This class would inherit from &lt;code&gt;Bottle&lt;/code&gt;, and thanks to LSP, we can substitute &lt;code&gt;Bottle&lt;/code&gt; with &lt;code&gt;BottleVariant&lt;/code&gt; in our program without issues.&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;BottleVariant&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Bottle&lt;/span&gt;   
        &lt;span class="c1"&gt;# Specialized implementation... &lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Act IV: ISP and the Art of Interfaces
&lt;/h3&gt;

&lt;p&gt;Our classes use simple, clear interfaces. Each method does one thing and is used by the clients of the class. This adherence to ISP ensures that we don't have unnecessary dependencies in our classes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Act V: Embracing DIP with Abstractions
&lt;/h3&gt;

&lt;p&gt;Finally, our &lt;code&gt;BeerWall&lt;/code&gt; class depends on an abstraction (&lt;code&gt;Bottle&lt;/code&gt;) and not on a concrete class. This is a simple form of DIP and allows us to change the underlying class (&lt;code&gt;Bottle&lt;/code&gt;) without affecting &lt;code&gt;BeerWall&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 The Testing Suite
&lt;/h2&gt;

&lt;p&gt;No OOP discussion is complete without testing. We'll demonstrate how to write simple tests for our classes using MiniTest, a testing suite included with Ruby by default. Create &lt;code&gt;99_bottels_oop_test.rb&lt;/code&gt;file.&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;'minitest/autorun'&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'99_bottels_oop'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BottleNumberTest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Minitest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Test&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;
        &lt;span class="vi"&gt;@beer_wall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;BeerWall&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="mi"&gt;99&lt;/span&gt;&lt;span class="p"&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;test_the_first_verse&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"99 bottles of beer on the wall, 99 bottles of beer.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
        &lt;span class="s2"&gt;"Take one down and pass it around, 98 bottles of beer on the wall.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@beer_wall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&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;test_another_verse&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"89 bottles of beer on the wall, 89 bottles of beer.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
        &lt;span class="s2"&gt;"Take one down and pass it around, 88 bottles of beer on the wall.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@beer_wall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;89&lt;/span&gt;&lt;span class="p"&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;test_verse_2&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2 bottles of beer on the wall, 2 bottles of beer.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
        &lt;span class="s2"&gt;"Take one down and pass it around, 1 bottle of beer on the wall.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@beer_wall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verse&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="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_verse_1&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1 bottle of beer on the wall, 1 bottle of beer.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
        &lt;span class="s2"&gt;"Take one down and pass it around, no more bottles of beer on the wall.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@beer_wall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verse&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="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_verse_0&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"no more bottles of beer on the wall, no more bottles of beer.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 
        &lt;span class="s2"&gt;"Go to the store and buy some more, 99 bottles of beer on the wall.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@beer_wall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&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;Rub &lt;code&gt;ruby 99_bottels_oop_test.rb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why OOP?&lt;/em&gt; Testing is a fundamental part of OOP, ensuring each object behaves as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 Comparison with Procedural Approach
&lt;/h2&gt;

&lt;p&gt;Let's compare this OOP solution with the procedural approach from the previous article.&lt;/p&gt;

&lt;p&gt;In the procedural approach, we wrote a script where the logic flowed in a straight line. Functions were called in sequence, and the data was passed around from one function to another. This approach is straightforward to understand when the problem is simple. It's like following a recipe: each step is laid out, and you move from one to the next in order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros of the Procedural Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;: For small scripts or simple problems, procedural code can be more straightforward to write and understand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;: Sometimes, procedural code can be faster because it involves less abstraction and fewer method calls.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons of the Procedural Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: As the complexity of the problem grows, procedural code can become harder to maintain and understand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reusability&lt;/strong&gt;: It's often more challenging to reuse parts of procedural code in other programs without modification.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand, the OOP approach encapsulates data and behaviour into objects. This mirrors real-world entities and allows for more complex interactions. Objects know how to manage their state and behaviour, leading to code that is more modular and easier to extend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros of the OOP Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modularity&lt;/strong&gt;: Objects can be easily reused across different parts of the program or even in different programs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maintainability&lt;/strong&gt;: OOP makes it easier to keep the codebase organized and to manage complexity, especially as the project grows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: Through inheritance and polymorphism, new functionality can be introduced with minimal changes to existing code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons of the OOP Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complexity&lt;/strong&gt;: The additional layers of abstraction in OOP can make it more difficult to understand for beginners.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Overhead&lt;/strong&gt;: Object creation and method calls can introduce performance overhead.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧩 Conclusion and share
&lt;/h2&gt;

&lt;p&gt;Through this exploration of the "99 Bottles of Beer" problem, we've delved deep into the nuances of Object-Oriented Programming. By shifting our perspective from procedural to OOP, we've transformed a straightforward script into a well-orchestrated ensemble of objects, each playing its part in harmony.&lt;/p&gt;

&lt;p&gt;This journey has been as much about learning and applying OOP principles as it has been about inviting collaboration and sharing. In the &lt;a href="https://ahmednadar.hashnode.dev/a-ruby-serenade-for-99-bottles-of-beer"&gt;previous post&lt;/a&gt;, I shared my &lt;a href="https://github.com/AhmedNadar/99BottlesChallenge"&gt;GitHub repository&lt;/a&gt; with the solution that employed a procedural approach. Now, I encourage you to visit the repository again to see the &lt;a href="https://github.com/AhmedNadar/99BottlesChallenge/tree/main/AhmedNadar/OOP"&gt;OOP solution in action&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm eager to hear your thoughts on the approaches we've discussed. Which do you lean towards in your own practice—procedural or OOP—and why? Your insights and diverse solutions enrich the conversation and contribute to a broader understanding of problem-solving in programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Further Resources
&lt;/h2&gt;

&lt;p&gt;For those looking to deepen their understanding of OOP in Ruby, here are some resources to get you started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://sandimetz.com/99bottles"&gt;Sandi Metz's "99 Bottles of OOP"&lt;/a&gt; - A deeper dive into OOP using our beloved beer song.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.poodr.com"&gt;Practical Object-Oriented Design in Ruby&lt;/a&gt; - Sandi Metz's guide to OOP principles in Ruby.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Until next time, Happy Coding 😀💎💻&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>oop</category>
      <category>codenewbie</category>
      <category>developer</category>
    </item>
    <item>
      <title>A Ruby Serenade for 99 Bottles of Beer</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Fri, 03 Nov 2023 18:12:36 +0000</pubDate>
      <link>https://forem.com/ahmednadar/a-ruby-serenade-for-99-bottles-of-beer-2o63</link>
      <guid>https://forem.com/ahmednadar/a-ruby-serenade-for-99-bottles-of-beer-2o63</guid>
      <description>&lt;p&gt;Hello, budding Ruby enthusiasts! 🌟&lt;/p&gt;

&lt;p&gt;Have you ever heard of the song &lt;a href="https://en.wikipedia.org/wiki/99_Bottles_of_Beer"&gt;99 Bottles of Beer on The Wall&lt;/a&gt;? It's the kind of catchy tune that’s perfect for passing time with friends or family as you cruise down the vast stretches of highways in the US or Canada. With its repetitive melody and simple lyrics, it sticks in your head whether you want it to or not.&lt;/p&gt;

&lt;p&gt;I first stumbled upon a quirky connection between this earworm and coding a few years back, thanks to &lt;a href="https://sandimetz.com/about"&gt;Sandi Metz&lt;/a&gt;'s enlightening talk at a Ruby conference. Sandi, a maestro of clean, maintainable OOP designs, has a knack for spinning traditional teaching methods on their head. Her approach is as refreshing as a cold brew on a hot day, and if you're a programmer aiming to sharpen your skills, her &lt;a href="https://www.youtube.com/@Confreaks/search?query=sandi%20metz"&gt;videos&lt;/a&gt;—courtesy of the splendid folks at &lt;a href="https://www.confreaks.com/how-we-work"&gt;Confreaks&lt;/a&gt;—are a treasure trove.&lt;/p&gt;

&lt;p&gt;Sandi's fondness for the "99 Bottles" ditty isn't just for kicks; she's leveraged its repetitive charm to unravel the intricacies of &lt;a href="https://en.wikipedia.org/wiki/Object-oriented_programming"&gt;OOP&lt;/a&gt; (Object-Oriented Programming). And yes, she's even authored a book, aptly titled &lt;a href="https://sandimetz.com/99bottles"&gt;99 Bottles of OOP&lt;/a&gt;, which I'm thoroughly enjoying and heartily endorse.&lt;/p&gt;

&lt;p&gt;Today's session isn't about vocal ranges or hitting the perfect pitch, although I'm sure you have a lovely voice and I'd not stop your karaoke party 🎙️. Instead, we're diving into a melody that echoes through the halls of coding exercises: "&lt;strong&gt;99 Bottles of Beer&lt;/strong&gt;." This classic tune is a programming pilgrimage, and for Ruby enthusiasts, it's a delightful way to tinker with loops, conditionals, and OOP concepts. By the end of this post, you'll have a new party trick to show off at your next developer meetup.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 The Goal
&lt;/h3&gt;

&lt;p&gt;Imagine a wall lined with 99 bottles of beer. The song counts down each bottle as it's "&lt;strong&gt;taken down and passed around&lt;/strong&gt;," until there are none left, then it's time to buy some more. Our mission, should we choose to accept it, is to write a Ruby script that sings this song from start to finish.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠️ Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before we start crooning in code, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A sprinkle of Ruby syntax knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ruby, gleaming and ready on your machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A text editor, like VS Code, Atom, or even Notepad.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Got everything? Superb! Let's get coding!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Comprehending the Composition
&lt;/h3&gt;

&lt;p&gt;Our song has a repetitive structure, perfect for a loop. But, there's a twist! When we reach 1 bottle, we can't say "bottles" anymore—English is picky like that. And when there are no more bottles, the song changes its tune. Check out part of the lyrics below, and pay attention to the last three sections.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;98 bottles of beer on the wall, 98 bottles of beer. Take one down and pass it around, 97 bottles of beer on the wall.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;... ... ... ... ...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2 bottles of beer on the wall, 2 bottles of beer. Take one down and pass it around, 1 bottle of beer on the wall.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;1 bottle of beer on the wall, 1 bottle of beer. Take one down and pass it around, no more bottles of beer on the wall.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Setting the Stage
&lt;/h3&gt;

&lt;p&gt;Create a new file named &lt;code&gt;ninety_nine_bottles.rb&lt;/code&gt;. This will be our stage for the performance. To run it, we'll use the command line charm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Ready for the spotlight? Let's go!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: The Loop of Lyrics
&lt;/h3&gt;

&lt;p&gt;Ruby has a beautiful way to &lt;a href="https://apidock.com/ruby/Integer/downto"&gt;count down&lt;/a&gt; with &lt;code&gt;downto&lt;/code&gt;. It's like a staircase from 99 to 0:&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="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&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;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# This is where the magic happens...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside this loop, we'll call forth our verses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: A Methodical Melody
&lt;/h3&gt;

&lt;p&gt;Singular and plural bottles need different words. Let's tune our method to handle that:&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;def&lt;/span&gt; &lt;span class="nf"&gt;print_bottle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;  
      &lt;span class="s2"&gt;"no more bottles"&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; 
      &lt;span class="s2"&gt;"1 bottle"&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bottles"&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;This method serenades us with the right words for each number.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Verses in Verse
&lt;/h3&gt;

&lt;p&gt;Now, the &lt;code&gt;print_verse&lt;/code&gt; method will print each verse based on the number of bottles:&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;def&lt;/span&gt; &lt;span class="nf"&gt;print_verse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;positive?&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;print_bottle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer on the wall, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;print_bottle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer."&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Take one down and pass it around, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;print_bottle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&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="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer on the wall.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"No more bottles of beer on the wall, no more bottles of beer."&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Go to the store and buy some more, 99 bottles of beer on the wall.&lt;/span&gt;&lt;span class="se"&gt;\n\n&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;Our loop now calls &lt;code&gt;print_verse&lt;/code&gt;, making the song unfold:&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="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;print_verse&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Refining the Rhapsody (Optional)
&lt;/h3&gt;

&lt;p&gt;As our code croons perfectly, can we make it more elegant? Refactoring is like poetry editing—it's an art. Look at your code and ask, "Can I make this clearer? More Ruby-esque?" Don't worry if this step seems tricky—it comes with practice!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: The Grand Finale
&lt;/h3&gt;

&lt;p&gt;Run your Ruby script and watch as the verses dance on your screen. It's a sing-along in text!&lt;/p&gt;

&lt;h3&gt;
  
  
  🖥️ Peek at My Code
&lt;/h3&gt;

&lt;p&gt;Before we reach our coding crescendo, if you're itching to see a finished version or need a little inspiration, check out &lt;a href="https://github.com/AhmedNadar/99BottlesChallenge"&gt;my solution on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 Share Your Rendition
&lt;/h3&gt;

&lt;p&gt;Now, it's your turn to take the stage! How would you serenade the "&lt;strong&gt;99 Bottles of Beer&lt;/strong&gt;" tune in Ruby? Everyone has their unique coding style, and I'd love to hear your verses. Share your approach to solving this problem by adding your solution to the &lt;a href="https://github.com/AhmedNadar/99BottlesChallenge"&gt;99 Bottles of Beer Ruby Challenge&lt;/a&gt; repo. Let's see how many variations we can compile from our creative community. Here’s how you can participate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Fork &lt;a href="https://github.com/AhmedNadar/99BottlesChallenge"&gt;the repository&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add your solution to the repository in a new directory named after your GitHub username.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Commit your changes and push them to your fork.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Submit a pull request with your solution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's a fun way to get involved in open source and to see your code alongside solutions from other developers. Plus, it's a great addition to your coding portfolio!&lt;/p&gt;

&lt;h3&gt;
  
  
  🎤 Encore
&lt;/h3&gt;

&lt;p&gt;Now that you've automated a song, learned some Ruby, and maybe even contributed to an open-source project, it's time to take a bow. Remember, programming is as much about community and sharing as it is about solving problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Further Learning
&lt;/h3&gt;

&lt;p&gt;If you enjoyed this, check Sandi's other book about &lt;a href="https://www.poodr.com"&gt;Practical Object-Oriented Design&lt;/a&gt;, and explore more with &lt;a href="https://ruby-doc.org/"&gt;Ruby's documentation&lt;/a&gt; and &lt;a href="https://guides.rubyonrails.org/"&gt;Rails guide&lt;/a&gt; for your next symphony.&lt;/p&gt;

&lt;p&gt;Until next time, keep coding to the rhythm of your heart's beat, and let Ruby be your muse! 💎💻&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>webdev</category>
      <category>rails</category>
      <category>programming</category>
    </item>
    <item>
      <title>How Rails inflections work their magic, turning 'UI' into 'Ui'</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Tue, 24 Oct 2023 11:00:00 +0000</pubDate>
      <link>https://forem.com/ahmednadar/how-rails-inflections-work-their-magic-turning-ui-into-ui-2ob8</link>
      <guid>https://forem.com/ahmednadar/how-rails-inflections-work-their-magic-turning-ui-into-ui-2ob8</guid>
      <description>&lt;p&gt;Years ago, &lt;a href="https://www.karlton.org/2017/12/naming-things-hard/"&gt;Phil Karlton&lt;/a&gt; mentioned once, "that during my dad's time at Netscape, he did indeed throw a quote around, on more than one occasion, it is": &lt;br&gt;
&lt;strong&gt;There are only two hard things in Computer Science: cache invalidation and naming things&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In every developer's journey, there comes a point where we have to grapple with names. Whether it's naming a new startup, a pet project, your kid 😉 or simply figuring out what to call that new variable, naming is an art. But what if I told you that Rails has a special magic trick up its sleeve to help with naming? Welcome to the world of Rails inflections.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. Setting the Stage, Why Inflections?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine working on an app, and suddenly you find yourself fumbling around with pluralizations and singularizations. You might think, "Okay, I'll just add an 's' at the end, and call it a day" but then irregular words like "person", "wolf", "loaf", "tooth" or even regular words in the same case "NASA" throw a wrench in your plans. That's where Rails' inflections come in. &lt;/p&gt;

&lt;p&gt;Inflections in Rails are all about rules. Rules that define how words change their form, especially in the context of pluralization and singularization. And as with all things Rails, there's a convention for that. You've got to appreciate and love convention ❤️ 💎&lt;/p&gt;

&lt;p&gt;Picture this, I was on a quest to create a namespaced view component, something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails generate component UI::Container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expecting Rails to generate a neat &lt;code&gt;UI::ContainerComponent&lt;/code&gt;, I was left scratching my head when I saw this instead:&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;module&lt;/span&gt; &lt;span class="nn"&gt;Ui&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContainerComponent&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ViewComponent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
    &lt;span class="o"&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;"Ui?" I thought. "I explicitly said 'UI'!"&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Rails' Inflection Shenanigans&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For those new to the term, inflection in Rails refers to the ways our beloved framework handles singulars, plurals, acronyms, and other linguistic peculiarities. It's what magically gives us &lt;code&gt;person&lt;/code&gt; -&amp;gt; &lt;code&gt;people&lt;/code&gt; or &lt;code&gt;mouse&lt;/code&gt; -&amp;gt; &lt;code&gt;mice&lt;/code&gt;. But sometimes, this magic can feel more like a trick!&lt;/p&gt;

&lt;p&gt;By default, Rails doesn't treat "UI" as an acronym but as any other word. So, in its quest to be helpful, it transformed "UI" to camel-cased "Ui"!"&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Taking Back Control with Custom Inflections&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Determined to have my component named &lt;code&gt;UI::ContainerComponent&lt;/code&gt;, I ventured into Rails' inflection rules. And voila! A simple addition to the inflections initializers &lt;code&gt;config/initializers/inflections.rb&lt;/code&gt; did the trick:&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="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:en&lt;/span&gt;&lt;span class="p"&gt;)&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;acronym&lt;/span&gt; &lt;span class="s2"&gt;"UI"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in place, Rails recognized "UI" as an all-uppercase acronym. Problem solved!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Delving into ActiveSupport::Inflector&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Rails provides a multitude of tools under the hood to make our lives easier, and one of those tools is the &lt;code&gt;ActiveSupport::Inflector&lt;/code&gt; &lt;a href="https://github.com/rails/rails/blob/main/activesupport/lib/active_support/inflector/inflections.rb"&gt;module&lt;/a&gt;. If you've ever wondered how Rails magically handles word transformations, pluralizations, singularizations, and the like, this module is the sorcerer behind the curtain.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;01 - A Peek into Inflections&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Inflections, in the linguistic sense, refer to the modifications of a word to express different grammatical categories. In Rails, inflections help in handling words that don't follow the typical pluralization or singularization rules and other word-based transformations.&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;module&lt;/span&gt; &lt;span class="nn"&gt;ActiveSupport&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Inflector&lt;/span&gt;
    &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="c1"&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;h4&gt;
  
  
  &lt;strong&gt;02 - The Power of the Inflector Class&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;At the core of the Inflector module is the &lt;code&gt;Inflections&lt;/code&gt; &lt;a href="https://github.com/rails/rails/blob/main/activesupport/lib/active_support/inflector/inflections.rb#L30"&gt;class&lt;/a&gt;. It's a rule book that Rails consults every time it needs to transform words. This class holds rules for pluralizations, singularizations, acronyms, and more. Developers can extend or modify the default behaviour to cater to specific needs, ensuring Rails can handle a vast array of word transformations.&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;Inflections&lt;/span&gt;
  &lt;span class="vi"&gt;@__instance__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Concurrent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="c1"&gt;# ... (the rest of the class)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a quick glance at some of the key methods in the &lt;code&gt;Inflections&lt;/code&gt; class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;acronym(word)&lt;/code&gt;&lt;/strong&gt;:  It identifies terms that should remain uppercase.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;acronym&lt;/span&gt; &lt;span class="s1"&gt;'API'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, &lt;code&gt;camelize('api_controller')&lt;/code&gt; will result in &lt;code&gt;'APIController'&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;plural(rule, replacement)&lt;/code&gt;&lt;/strong&gt;: Guides Rails in pluralizing words.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plural&lt;/span&gt; &lt;span class="sr"&gt;/^(ox)$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'\1en'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will pluralize "ox" to "oxen".&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;singular(rule, replacement)&lt;/code&gt;&lt;/strong&gt;: Assists Rails in singularizing words.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singular&lt;/span&gt; &lt;span class="sr"&gt;/^(ox)en/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'\1'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This transforms "oxen" back to "ox".&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;irregular(singular, plural)&lt;/code&gt;&lt;/strong&gt;: Handles words that defy typical pluralization patterns.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;irregular&lt;/span&gt; &lt;span class="s1"&gt;'person'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'people'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures "person" pluralizes to "people" and not "persons".&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;uncountable(words)&lt;/code&gt;&lt;/strong&gt;: Informs Rails about words that don't have a plural form.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uncountable&lt;/span&gt; &lt;span class="s1"&gt;'information'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures "information" remains "information" even when pluralized.&lt;/p&gt;

&lt;p&gt;By understanding and using these methods, you can ensure that Rails handles word transformations in the way you intend.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;03- Extending the Inflector's Reach&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;inflections&lt;/code&gt; &lt;a href="https://github.com/rails/rails/blob/main/activesupport/lib/active_support/inflector/inflections.rb#L265"&gt;method&lt;/a&gt; in the &lt;code&gt;ActiveSupport::Inflector&lt;/code&gt; module allows developers to add or modify inflection rules based on their needs, even for different locales.&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;def&lt;/span&gt; &lt;span class="nf"&gt;inflections&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:en&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;block_given?&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="no"&gt;Inflections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="no"&gt;Inflections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_or_fallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="p"&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;h3&gt;
  
  
  &lt;strong&gt;5. Customizing Inflection Rules&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Not all words follow the standard English rules for pluralization or singularization. And here's where the true power of Rails inflections shines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Irregular Inflections&lt;/strong&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="s2"&gt;"foot"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluralize&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; "foots"  # Oops!&lt;/span&gt;

&lt;span class="c1"&gt;# Let's fix this in config/initializers/inflections.rb&lt;/span&gt;
&lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:en&lt;/span&gt;&lt;span class="p"&gt;)&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;irregular&lt;/span&gt; &lt;span class="s2"&gt;"foot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"feet"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="s2"&gt;"foot"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluralize&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; "feet"  # That's better!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;- Uncountable Inflections&lt;/strong&gt;:&lt;br&gt;
Some words just don't like to be counted. For instance, "milk". Using inflections, you can specify such words.&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="s2"&gt;"milk"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluralize&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; "milks"  # Wait, what?&lt;/span&gt;

&lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:en&lt;/span&gt;&lt;span class="p"&gt;)&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uncountable&lt;/span&gt; &lt;span class="s2"&gt;"milk"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="s2"&gt;"milk"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluralize&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; "milk"  # Perfect!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;- Acronym Inflections&lt;/strong&gt;:&lt;br&gt;
Remember our little &lt;code&gt;UI&lt;/code&gt; vs. &lt;code&gt;Ui&lt;/code&gt; debacle? Acronym inflections come to the rescue here.&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="s2"&gt;"html5"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;camelize&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; "Html5"&lt;/span&gt;

&lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Inflector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflections&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:en&lt;/span&gt;&lt;span class="p"&gt;)&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;inflect&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;acronym&lt;/span&gt; &lt;span class="s2"&gt;"HTML5"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="s2"&gt;"html5"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;camelize&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; "HTML5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;6. Further Reading and Exploration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For those keen on diving deeper into Rails inflections, the &lt;a href="https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#customizing-inflections"&gt;Rails documentation&lt;/a&gt; and &lt;a href="https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html"&gt;Inflector API&lt;/a&gt; are a goldmine. Additionally, I recommend exploring the &lt;a href="https://github.com/rails/rails/blob/main/activesupport/lib/active_support/inflector/inflections.rb"&gt;Rails source code&lt;/a&gt; to understand the intricacies of the &lt;code&gt;ActiveSupport::Inflector&lt;/code&gt; module. It's not just educational; it's a testament to the elegant design of Rails.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;7. Pro Tips for the Avid Rails Developer&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Explore Before You Define&lt;/strong&gt;: Before you rush to define a new inflection, ensure it's not already handled by Rails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comment Your Custom Inflections&lt;/strong&gt;: If you're adding a custom rule, a brief comment explaining the rationale can be invaluable for your future self and fellow developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less is More&lt;/strong&gt;: While the power to define any word behavior is tempting, over-customization can lead to confusing code. Stick to the necessary.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;8. Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Rails, in its essence, is designed to make developers' lives easier. Its convention-over-configuration philosophy ensures that you're up and running in no time. However, with every convention, there are occasional outliers. Inflections, a seemingly minor feature, play a pivotal role in addressing these nuances.&lt;/p&gt;

&lt;p&gt;From guiding Rails on how to handle irregular words to ensuring that acronyms are treated right, inflections become an indispensable tool in a developer's arsenal. The &lt;code&gt;ActiveSupport::Inflector&lt;/code&gt; module is like a Swiss Army knife, offering a plethora of methods to juggle words in ways you never imagined possible.&lt;/p&gt;

&lt;p&gt;But as with all powerful tools, it's essential to wield them with care. Over-reliance or unnecessary customization can muddy the waters, making it harder for fellow developers to navigate your codebase. It's always a balance between convention and customization.&lt;/p&gt;

&lt;p&gt;Until next time, Happy Coding 🧑🏽‍💻 == Happy days 😁&lt;/p&gt;

</description>
      <category>rails</category>
      <category>programming</category>
      <category>ruby</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Mastering Rails Web Navigation with link_to and button_to Helpers - Part 2</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Sun, 22 Oct 2023 19:26:12 +0000</pubDate>
      <link>https://forem.com/ahmednadar/mastering-rails-web-navigation-with-linkto-and-buttonto-helpers-part-2-4dk1</link>
      <guid>https://forem.com/ahmednadar/mastering-rails-web-navigation-with-linkto-and-buttonto-helpers-part-2-4dk1</guid>
      <description>&lt;p&gt;Welcome to Part 2 of our Rails Web Navigation tutorial!&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/ahmednadar/mastering-rails-web-navigation-with-linkto-and-buttonto-helpers-part-1-3gbg"&gt;Part 1&lt;/a&gt;, we embarked on a cosmic journey through the Rails galaxy, exploring the intricacies of the Rails web navigation system. We delved deep into how Rails handles web requests, understanding the celestial dance between ActionController and ActionView. We also navigated the Middleware Nebula, gaining insights into the pivotal role middleware plays in processing web requests.&lt;/p&gt;

&lt;p&gt;Having laid the groundwork in Part 1, we're now poised to dive into the heart of web navigation in Rails. In this part, we'll focus on the magic of the &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; helpers, starting with the ever-versatile &lt;code&gt;link_to&lt;/code&gt;. These helpers are the unsung heroes that power the seamless navigation experience we often take for granted. So, without further ado, let's dive right in!&lt;/p&gt;

&lt;p&gt;Great, let’s get started!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TABLE OF CONTENTS (Part 2)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Link_to

&lt;ul&gt;
&lt;li&gt;Definition&lt;/li&gt;
&lt;li&gt;Syntax&lt;/li&gt;
&lt;li&gt;Delete with link_to&lt;/li&gt;
&lt;li&gt;Delete Link With Confirmation&lt;/li&gt;
&lt;li&gt;Ajax links with remote&lt;/li&gt;
&lt;li&gt;link_to Variants&lt;/li&gt;
&lt;li&gt;Hotwire&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

button_to

&lt;ul&gt;
&lt;li&gt;Definition&lt;/li&gt;
&lt;li&gt;Syntax&lt;/li&gt;
&lt;li&gt;Submit with options&lt;/li&gt;
&lt;li&gt;Hotwire&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Final Words&lt;/li&gt;

&lt;li&gt;Frequently Asked Questions&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;link to&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  link to Definition
&lt;/h2&gt;

&lt;p&gt;Let me guess, you found your way to this page by clicking on a link from another page, right? That's the beauty of the anchor element, which creates links between pages, files, and locations or external pages. In the world of Rails, we have amazing helper methods, including &lt;code&gt;link_to&lt;/code&gt;, that make navigating through your Rails application a breeze. This helper generates an HTML &lt;code&gt;&amp;lt;a href=" "&amp;gt;...&amp;lt;/a&amp;gt;&lt;/code&gt; tag that directs you to a specified URL target. Here's the basic format of a &lt;code&gt;link_to&lt;/code&gt; tag and its corresponding HTML link:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to 'Rails', 'https://rubyonrails.org/' %&amp;gt;
# =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="ss"&gt;:/&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rubyonrails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Ruby&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming you have a &lt;code&gt;User&lt;/code&gt; model and a corresponding &lt;code&gt;user_path&lt;/code&gt; helper.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to user.name, user_path(user) %&amp;gt;
=&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/users/123"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Ahmed&lt;/span&gt; &lt;span class="no"&gt;Nadar&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;

&amp;lt;%= link_to car.type, car_path(@car) %&amp;gt;
# even better
&amp;lt;%= link_to car.type, @car %&amp;gt;
# =&amp;gt; &amp;lt;a href="/&lt;/span&gt;&lt;span class="n"&gt;cars&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;Tesla&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, with &lt;code&gt;link_to&lt;/code&gt;, all you need is a string of text Ruby on Rails for the link's visible name, followed by the path to the destination URL. But that's not all &lt;code&gt;link_to&lt;/code&gt; can do! It's able to recognize instances and generate related paths for them. This is useful when you have a list of items (objects) and you want to redirect the user to the show page of the selected item. In the example given, we are redirecting the user to the page of a car, where &lt;code&gt;@car&lt;/code&gt; represents a specific instance of a car.&lt;/p&gt;

&lt;h2&gt;
  
  
  link to Syntax
&lt;/h2&gt;

&lt;p&gt;As we discovered earlier, the &lt;code&gt;link_to&lt;/code&gt; helper method is pretty useful for creating anchor tags that link to specified URL targets. But did you know that the method's full syntax is even more powerful? That's right! The complete method signature includes additional parameters that allow you to customize the link even further. Here's the full signature of the &lt;code&gt;link_to&lt;/code&gt; method:&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="n"&gt;link_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break it down.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;link_to&lt;/code&gt; method accepts several parameters, with some being mandatory and others optional.&lt;/p&gt;

&lt;p&gt;*&lt;code&gt;name&lt;/code&gt;: This parameter by default is &lt;code&gt;nil&lt;/code&gt;. It is the text that appears as the link's visible text. It is what you see on the page. If &lt;code&gt;name&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt;, the URL is used as the link visible text. &lt;code&gt;name&lt;/code&gt; can be string, image tag, or a combination of both as we will see soon.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to 'Home', root_path %&amp;gt;&amp;lt;/li&amp;gt;
# =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://rubyonrails.org/"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;

&amp;lt;span&amp;gt;&amp;lt;%= link_to "https:/&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rubyonrails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="s2"&gt;" %&amp;gt;&amp;lt;/span&amp;gt;
# =&amp;gt; &amp;lt;a href="&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="ss"&gt;:/&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rubyonrails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;https://rubyonrails.org/&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;code&gt;options&lt;/code&gt;: is another parameter that &lt;code&gt;link_to&lt;/code&gt; accepts. By default, it is &lt;code&gt;nil&lt;/code&gt;. It is responsible for defining the URL or route for the link. If it is a string, it is represented as the URL of the link. If it is a hash, it follows the defined route. There are two styles of routes: the older-style parameters routes, which no one uses anymore, and the new-style named routes.&lt;/p&gt;

&lt;p&gt;The older-style parameters routes use the keys &lt;code&gt;controller&lt;/code&gt;, &lt;code&gt;action&lt;/code&gt;, and &lt;code&gt;id&lt;/code&gt; to specify the controller, action, and ID of the resource being linked to, respectively. It is not recommended to use this style of routing anymore.&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="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"User"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;controller: &lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;action: &lt;/span&gt;&lt;span class="s2"&gt;"show"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="vi"&gt;@user&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;a href="/users/show/1"&amp;gt;User&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And there's the current Rails style of RESTful routes, which is considered better practice.
&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="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"User"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@user&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;a href="/users/1"&amp;gt;User&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;code&gt;html_options&lt;/code&gt; is another parameter that the &lt;code&gt;link_to&lt;/code&gt; accepts. It is nil by default, and it is used to define &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes" rel="noopener noreferrer"&gt;HTML attributes&lt;/a&gt; that will be added to the link's &lt;code&gt;a&lt;/code&gt; tag. You can use this parameter to add &lt;code&gt;class&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;target&lt;/code&gt;, &lt;code&gt;rel&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, and &lt;code&gt;data&lt;/code&gt; attributes to the link, among others. By doing this, you can customize the link's behaviour and appearance.&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="n"&gt;link_to&lt;/span&gt; &lt;span class="s1"&gt;'AvoHQ'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'https://avohq.io'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s1"&gt;'to_home'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;target: &lt;/span&gt;&lt;span class="s1"&gt;'_blank'&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;a href="https://avohq.io" class="to_home" target="_blank"&amp;gt;AvoHQ&amp;lt;/a&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Adding a class and id to the link&lt;/span&gt;
&lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"AvoHQ"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"https://avohq.io/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-primary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="s2"&gt;"avohq-link"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;a href="https://avohq.io/" class="btn btn-primary" id="avohq-link"&amp;gt;AvoHQ&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we create a link to AvoHQ's homepage with the visible text "AvoHQ". Additionally, it includes CSS &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;target&lt;/code&gt; attributes that are added to the a tag of the link.&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="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Avo Blog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;posts_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="s2"&gt;"blog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"avo_blog"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;a href="/posts" class="avo_blog" id="blog"&amp;gt;Avo Blog&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code generates a link to AvoHQ's blog page with the text "Avo Blog" and a &lt;code&gt;CSS&lt;/code&gt; and &lt;code&gt;id&lt;/code&gt; attributes are added to the link's &lt;code&gt;a&lt;/code&gt; tag.&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="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Comment section"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;anchor: &lt;/span&gt;&lt;span class="s2"&gt;"section"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;a href="/users/1#section"&amp;gt;Comment section&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code generates a link to the comment section on the same user show page with the text "Comment section" and an &lt;code&gt;anchor&lt;/code&gt; attribute added to the link to target that specific section.&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="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Avo Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"http://www.avohq.io/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;target: &lt;/span&gt;&lt;span class="s2"&gt;"_blank"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;rel: &lt;/span&gt;&lt;span class="s2"&gt;"nofollow"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;a href="http://www.avohq.io/" target="_blank" rel="nofollow"&amp;gt;Avo Home&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code generates a link to the Avo home page with the text "Avo Home", and it also adds the &lt;code&gt;target&lt;/code&gt; and &lt;code&gt;rel&lt;/code&gt; attributes to the link's &lt;code&gt;a&lt;/code&gt; tag.&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="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Avo search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;controller: &lt;/span&gt;&lt;span class="s2"&gt;"searches"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;query: &lt;/span&gt;&lt;span class="s2"&gt;"ruby on rails admin panel"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;a href="/searches?query=ruby+on+rails+admin+panel"&amp;gt;Avo search&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code generates a link to the search page with the text "Avo search". In addition, a controller with the name 'searches' and a query attribute with the value 'ruby on rails admin panel' is added to the link's a tag.&lt;/p&gt;

&lt;p&gt;*&lt;code&gt;&amp;amp;block&lt;/code&gt; parameter is optional and is &lt;code&gt;nil&lt;/code&gt; by default. It's not used often but can be useful for making the code more readable and easier to understand. Imagine you have a long text that is hard to fit into the &lt;code&gt;name&lt;/code&gt; parameter. In this case, you can pass the link text inside a block of code that generates the content of the link.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to(@car) do %&amp;gt;
  &amp;lt;strong&amp;gt;&amp;lt;%=&lt;/span&gt; &lt;span class="vi"&gt;@car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Check&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;car!&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;
&amp;lt;% end %&amp;gt;
&amp;lt;a href="/&lt;/span&gt;&lt;span class="n"&gt;cars&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;
  &amp;lt;strong&amp;gt;Tesla&amp;lt;/strong&amp;gt; -- &amp;lt;span&amp;gt;Check this car!&amp;lt;/span&amp;gt;
&amp;lt;/a&amp;gt;


&amp;lt;%= link_to "&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="ss"&gt;:/&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;avohq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;io&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="s2"&gt;" do %&amp;gt;
  &amp;lt;strong&amp;gt;AvoHQ&amp;lt;/strong&amp;gt; - The Best Rails Guide
&amp;lt;% end %&amp;gt;
&amp;lt;a href="&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="ss"&gt;:/&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;avohq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;io&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;
  &amp;lt;strong&amp;gt;AvoHQ&amp;lt;/strong&amp;gt; - The Best Rails Guide
&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another example:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to blog_path(@blog) do %&amp;gt;
  &amp;lt;i class=&lt;/span&gt;&lt;span class="s2"&gt;"fa fa-pencil"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/i&amp;gt; # fontawesome icons
  Edit
&amp;lt;% end %&amp;gt;

# =&amp;gt;
&amp;lt;a href="/&lt;/span&gt;&lt;span class="n"&gt;blogs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;
  &amp;lt;i class="&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pencil&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;&amp;lt;/i&amp;gt;
  Edit
&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this code generates a link to the &lt;code&gt;show&lt;/code&gt; action of the &lt;code&gt;BlogController&lt;/code&gt;, passing the &lt;code&gt;@blog&lt;/code&gt; ID as a parameter. The link's content will consist of a Font Awesome icon and the text "Edit".&lt;/p&gt;

&lt;p&gt;So far, we learned how &lt;code&gt;link_to&lt;/code&gt; works in its default mode, which is the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods" rel="noopener noreferrer"&gt;GET request&lt;/a&gt;. To refresh your memory, do you remember our fancy diagram from earlier? It illustrated the communication between the browser and the server, where a method was used to deliver the message of what the browser wants the server to do. If you don't recall, don't worry, it's normal to forget things. In this case, the &lt;code&gt;localhost/jobs&lt;/code&gt; URL is clicked by a user, and a successful request with a 200/OK response takes the user to the &lt;code&gt;Jobs&lt;/code&gt; page, which uses the &lt;code&gt;GET&lt;/code&gt; request method.&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%2Fyoxp2zn34ukozpk73s10.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%2Fyoxp2zn34ukozpk73s10.png" alt="link_to syntax"&gt;&lt;/a&gt;&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%2Fleev2k0ca76ttku1avmr.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%2Fleev2k0ca76ttku1avmr.png" alt="link_to syntax get reponse"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Delete with link to
&lt;/h2&gt;

&lt;p&gt;Did you know that there's another way &lt;code&gt;link_to&lt;/code&gt; can navigate? Yes, it's true! This method uses a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods" rel="noopener noreferrer"&gt;DELETE request&lt;/a&gt; to delete a record or a specific instance. Let's say you have a &lt;code&gt;@post&lt;/code&gt; instance and you want to delete it. In order to call the &lt;code&gt;destroy&lt;/code&gt; action on the &lt;code&gt;PostController&lt;/code&gt;, you need to use the &lt;code&gt;DELETE&lt;/code&gt; request method. You can achieve this by passing the &lt;code&gt;method: :delete&lt;/code&gt; hash as an option to the &lt;code&gt;link_to&lt;/code&gt; helper. For example, on the same token, you will be able to pass any method defined in your controllers to the &lt;code&gt;link_to&lt;/code&gt; helper. Here is how to use &lt;code&gt;delete&lt;/code&gt; method:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to "Delete post", post_path(@post), method: "delete" %&amp;gt;
# =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"nofollow"&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/posts/1"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Remove&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is worth noting that the &lt;code&gt;rel="nofollow"&lt;/code&gt; attribute is automatically added by Rails 'magic' as an added benefit for &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/SEO" rel="noopener noreferrer"&gt;Search Engine Optimization (SEO)&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delete Link With Confirmation
&lt;/h2&gt;

&lt;p&gt;Deleting a record is a necessary action, but it can be harsh and irreversible. To ensure that the user agrees to such a drastic action, we developers might want to prompt them with a message asking for confirmation and to prevent accidental deletion using &lt;code&gt;confirm&lt;/code&gt; method &lt;code&gt;{ confirm: "Are you sure?" }&lt;/code&gt;. The easiest way to add this feature is with a simple JavaScript alert box that will ask the user to confirm their delete request. Guess what, Rails magic does it for you, again. The alert can be implemented as shown below:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to "Delete post", post_path(@post), method: "delete", { confirm: "Are you sure?" } %&amp;gt;
# =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;confirm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Are you sure?"&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"nofollow"&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/jobs/1"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Delete&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fcheouiexirs9pdl160xh.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%2Fcheouiexirs9pdl160xh.png" alt="delete link With Confirmation window"&gt;&lt;/a&gt;&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%2Fongw1u40sm9jbkfrhcg9.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%2Fongw1u40sm9jbkfrhcg9.png" alt="delete link With Confirmation method/post"&gt;&lt;/a&gt;&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%2Ft3tazg4in139onsm18bn.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%2Ft3tazg4in139onsm18bn.png" alt="delete link With Confirmation method/delete"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ajax links with remote
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX" rel="noopener noreferrer"&gt;Ajax&lt;/a&gt; links, the superheroes of asynchronous requests that allow you to dynamically update your page content without the irritating full-page reloads. To create an Ajax link, all you need to do is use the &lt;code&gt;link_to&lt;/code&gt; method with the &lt;code&gt;remote: true&lt;/code&gt;. For instance, the following code creates an Ajax link that sends a GET request to the server when clicked:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to "Load More", "https://avohq.com/more", remote: true %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When clicked, this link triggers an Ajax request to the specified URL, allowing your web page to update without any hiccups. With the power of JavaScript or other client-side technologies such as &lt;a href="https://hotwired.dev/" rel="noopener noreferrer"&gt;Hotwire&lt;/a&gt; as we will discover soon, you can even process and display the server's response on your page.&lt;/p&gt;

&lt;h2&gt;
  
  
  link to Variants
&lt;/h2&gt;

&lt;p&gt;Rails not only empower you with the &lt;code&gt;link_to&lt;/code&gt; magic implementation, but it has more variations up its sleeve! Oh, yeah! Each of these variants helps you avoid complex code and makes your code clean by doing a specific communication job. These variants are:&lt;/p&gt;

&lt;p&gt;a-&lt;code&gt;link_to_unless_current(name, options = {}, html_options = {}, &amp;amp;block)&lt;/code&gt;&lt;br&gt;
Want to create a link only if it's not the current page? Try &lt;code&gt;link_to_unless_current!&lt;/code&gt; It creates a link but returns the name instead if it's the current page.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to_unless_current "Cars", cars_path %&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;link_to_unless_current&lt;/span&gt; &lt;span class="s2"&gt;"Dashboard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dashboard_path&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&amp;gt;

  # When you are on `/&lt;/span&gt;&lt;span class="n"&gt;cars&lt;/span&gt;&lt;span class="sb"&gt;`, this template will output:
  # =&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;Cars&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href="/dashboard"&amp;gt;Dashboard&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;/nav&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;b-&lt;code&gt;link_to_if(condition, name, options = {}, html_options = {}, &amp;amp;block)&lt;/code&gt;&lt;br&gt;
Want to create a link only under certain conditions? Use &lt;code&gt;link_to_if!&lt;/code&gt; It creates a link using options if a condition is true, otherwise, it returns the name.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to_unless(@current_user.nil?, 'Log In', new_user_registration_path %&amp;gt;
  &amp;lt;/li&amp;gt;

  # If the user is NOT logged in...
  # =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/users/signin/"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Log&lt;/span&gt; &lt;span class="no"&gt;In&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;c-&lt;code&gt;link_to_unless(condition, name, options = {}, html_options = {}, &amp;amp;block)&lt;/code&gt;&lt;br&gt;
Looking for a way to create a link only when a certain condition is false? Try &lt;code&gt;link_to_unless!&lt;/code&gt; It creates a link tag using a URL from options unless the condition is true, otherwise, only the name is returned.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to_unless(@current_user.nil?, 'Log In', new_user_registration_path %&amp;gt;
  &amp;lt;/li&amp;gt;

  # If the user is logged in...
  # =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/users/signin/"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Log&lt;/span&gt; &lt;span class="no"&gt;In&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Hotwire with link to
&lt;/h2&gt;

&lt;p&gt;If you think you have seen enough Rails magic, you are mistaken my friend. Rails have a new trick up its sleeve: &lt;a href="https://hotwired.dev/" rel="noopener noreferrer"&gt;Hotwire&lt;/a&gt;. And with the magical &lt;a href="https://turbo.hotwired.dev/" rel="noopener noreferrer"&gt;Turbo&lt;/a&gt; tool that comes with it, you can create modern, interactive web applications with minimal, or sometimes no JavaScript at all, providing users with an incredibly smooth experience.&lt;/p&gt;

&lt;p&gt;One of Turbo's key instruments is &lt;a href="https://turbo.hotwired.dev/handbook/drive" rel="noopener noreferrer"&gt;Drive&lt;/a&gt;, which enhances page-level navigation. It watches for link clicks and form submissions, performs them in the background, and updates the page without doing a full reload. And let me tell you, that's pretty darn amazing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;link_to&lt;/code&gt; default uses Turbo Drive for non-&lt;code&gt;GET&lt;/code&gt; (&lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;) requests, making it simple to create links that update the page content without a full reload. Perfect for actions like deleting, creating/updating records and displaying more content.&lt;/p&gt;

&lt;p&gt;For example, let's say you want to create a link that uses Hotwire to submit a &lt;code&gt;DELETE&lt;/code&gt; request to the server, with a confirmation dialog for the user to approve. Well, look no further:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to
    "Delete Post",
    post_path(post),
    method: :delete,
    data: { turbo_confirm: "Are you sure?" }
  %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When clicked, this link sends a &lt;code&gt;DELETE&lt;/code&gt; request to the server and displays a confirmation dialog for the user, (we have seen this before, nothing new here, right)! Turbo then processes the server response, and the page content is updated without a full page reload (That's magic). This feature makes it easy to create interactive web applications with minimal or no JavaScript and a smooth user experience. Why not give it a try and see the magic for yourself?&lt;/p&gt;

&lt;h2&gt;
  
  
  link to Conclusion
&lt;/h2&gt;

&lt;p&gt;Phew, it has been a journey. We've navigated our way through the astonishing Rails web navigation system. &lt;code&gt;link_to&lt;/code&gt; is one of the most powerful tools in Rails world. Effortlessly, you can generate HTML tags that glide you to pages, files, and beyond. Its signature is versatile, you can add blocks, instance variables, media, confirmation messages, and even delete objects. Additionally, it offers seamless variants, making link creation clutter-free, logical and magical.&lt;/p&gt;

&lt;h1&gt;
  
  
  button to
&lt;/h1&gt;

&lt;h2&gt;
  
  
  button-to-definition
&lt;/h2&gt;

&lt;p&gt;Similar to &lt;code&gt;link_to&lt;/code&gt;, &lt;code&gt;button_to&lt;/code&gt; is another handy helper method in Rails that creates a button element with a specified action. This helper generates a nifty &lt;code&gt;HTML&lt;/code&gt; form &lt;code&gt;&amp;lt;form action=" "&amp;gt;&amp;lt;button&amp;gt;...&amp;lt;/button&amp;gt;&amp;lt;/form&amp;gt;&lt;/code&gt; tag that performs the specified action submit when clicked. Here's the basic format of a button_to tag and its corresponding HTML form:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= button_to "Delete", post_path(@post), method: :delete %&amp;gt;
  # =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/posts/1"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_method"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Delete"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, with button_to, you need to specify the action (in this case, "Delete"), followed by the path to the destination URL &lt;code&gt;(post_path(@post))&lt;/code&gt;, and the method used for the action &lt;code&gt;(method: :delete)&lt;/code&gt;. When clicked, this button sends a &lt;code&gt;DELETE&lt;/code&gt; request to the specified URL. button_to. And that's not all! button_to accepts other options such as &lt;code&gt;:class&lt;/code&gt;, &lt;code&gt;:disabled&lt;/code&gt;, and &lt;code&gt;:form_class&lt;/code&gt; to customize the form element and its children.&lt;/p&gt;

&lt;p&gt;It's particularly useful for actions that require more than a simple link, such as creating or deleting records in a database. By default, button_to generates a form element with a hidden input for the method and a submit button with the specified label, making it easy to perform complex actions without having to write a lot of HTML and JavaScript code.&lt;/p&gt;

&lt;h2&gt;
  
  
  button to Syntax
&lt;/h2&gt;

&lt;p&gt;Ah, &lt;code&gt;button_to&lt;/code&gt; - another gem in the Rails toolbox! As we discovered earlier, &lt;code&gt;button_to&lt;/code&gt; is a helper method that generates a form element with a specified action, which is executed when the button is clicked. By now you would know that the method's full syntax is even more powerful. The complete method signature includes additional parameters that allow you to customize button_to even further. Here's the full signature of the &lt;code&gt;button_to&lt;/code&gt; method: &lt;code&gt;**button_to**(name = nil, options = nil, html_options = nil, &amp;amp;block)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's break it down.&lt;/p&gt;

&lt;p&gt;*&lt;code&gt;name&lt;/code&gt;: This parameter is optional and represents the text that appears on the button. If no &lt;code&gt;name&lt;/code&gt; is provided, the &lt;code&gt;button_to&lt;/code&gt; method will use the URL as the button text. You can use a string, an image tag, or a combination of both as the &lt;code&gt;name&lt;/code&gt; argument.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= button_to "Delete", post_path(@post), method: :delete %&amp;gt;&amp;lt;/li&amp;gt;
  # =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/posts/1"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_method"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Delete"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;code&gt;options&lt;/code&gt;: This parameter is optional and can take several forms. If it is a string, it is interpreted as the URL of the button's destination. If it is a hash, it can include a &lt;code&gt;:controller&lt;/code&gt;, &lt;code&gt;:action&lt;/code&gt;, and &lt;code&gt;:id&lt;/code&gt; keys to specify the controller, action, and ID of the resource being linked to, respectively (Similar to &lt;code&gt;link_to&lt;/code&gt;). Other options include :method to specify the HTTP method used for the action (e.g., &lt;code&gt;:post&lt;/code&gt;, &lt;code&gt;:put&lt;/code&gt;, &lt;code&gt;:delete&lt;/code&gt;), and &lt;code&gt;:data&lt;/code&gt; to specify additional data to be sent with the request.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;options&lt;/code&gt; parameter of &lt;code&gt;button_to&lt;/code&gt; can take a hash with additional options, like &lt;code&gt;:params&lt;/code&gt;, which specifies any additional parameters to be sent with the request. Here's an example:&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="n"&gt;button_to&lt;/span&gt; &lt;span class="s2"&gt;"New Article"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_article_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;params: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;time: &lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/articles/new"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[AUTH_TOKEN]"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"time"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[CURRENT_TIME]"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;New&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, a form element is generated with an action of &lt;code&gt;/articles/new&lt;/code&gt; and a method of &lt;code&gt;post&lt;/code&gt;. The &lt;code&gt;params&lt;/code&gt; option is used to add a hidden input field named "time" with the value of the current time. When the button is clicked, the form is submitted and the specified action is performed on the server.&lt;/p&gt;

&lt;p&gt;*&lt;code&gt;html_options&lt;/code&gt; is an optional parameter of the &lt;code&gt;button_to&lt;/code&gt;, Is &lt;code&gt;nil&lt;/code&gt; by default and is used to add HTML attributes to the button's &lt;code&gt;form&lt;/code&gt; and &lt;code&gt;button&lt;/code&gt; tags. Here are some examples of using the various &lt;code&gt;html_options&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;-&lt;code&gt;:method&lt;/code&gt;: This option specifies the HTTP verb (delete) to be used for the form submission. Here's an example:&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="n"&gt;button_to&lt;/span&gt; &lt;span class="s2"&gt;"Delete"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;method: :delete&lt;/span&gt;
  &lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/posts/:id"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_method"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"commit"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Delete"&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;disable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Delete"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[AUTH_TOKEN]"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-&lt;code&gt;:disabled&lt;/code&gt;: This option generates a disabled button. Here's an example:&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="n"&gt;button_to&lt;/span&gt; &lt;span class="s2"&gt;"Save"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;save_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;disabled: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/save"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[AUTH_TOKEN]"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt; &lt;span class="n"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"disabled"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Save&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-&lt;code&gt;:data&lt;/code&gt;: This option is used to add custom data attributes. Here's an example:&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="n"&gt;button_to&lt;/span&gt; &lt;span class="s2"&gt;"Submit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;submit_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;confirm: &lt;/span&gt;&lt;span class="s2"&gt;"Are you sure you want to submit?"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"button_to"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_method"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[AUTH_TOKEN]"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;confirm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Are you sure you want to submit?"&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Submit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-&lt;code&gt;:remote&lt;/code&gt;: This option allows the unnoticeable JavaScript drivers to control the form's submission behaviour. By default, this is an AJAX submit. Here's an example:&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="n"&gt;button_to&lt;/span&gt; &lt;span class="s2"&gt;"Delete"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;method: :delete&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;remote: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"button_to"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/posts/1"&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_method"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[AUTH_TOKEN]"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Delete&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-&lt;code&gt;:form&lt;/code&gt;: This option is a hash of attributes to be added to the &lt;code&gt;form&lt;/code&gt; tag. Here's an example:&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="n"&gt;button_to&lt;/span&gt; &lt;span class="s2"&gt;"Create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;form: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="s2"&gt;"create-form"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"create-form"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"UTF-8"&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/create"&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"create-form"&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"create-form"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[AUTH_TOKEN]"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"button"&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Create&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-&lt;code&gt;:form_class&lt;/code&gt;: This option is used to specify the class of the form within which the submit button will be placed. Here's an example:&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="n"&gt;button_to&lt;/span&gt; &lt;span class="s2"&gt;"Save"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;save_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;form_class: &lt;/span&gt;&lt;span class="s2"&gt;"save-form"&lt;/span&gt;
  &lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/save"&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"save-form"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[AUTH_TOKEN]"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Save&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-&lt;code&gt;:params&lt;/code&gt;: This option is a hash of parameters to be rendered as hidden fields within the form. Here's an example:&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="n"&gt;button_to&lt;/span&gt; &lt;span class="s2"&gt;"New Car"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_car_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;params: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;time: &lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/cars/new"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"time"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[CURRENT_TIME]"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;New&lt;/span&gt; &lt;span class="no"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-&lt;code&gt;&amp;amp;block&lt;/code&gt; is an optional parameter of the &lt;code&gt;button_to&lt;/code&gt;. It is nil by default and can be used to generate custom content for the button. This is useful when you want to add an icon or other custom HTML to the button.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= button_to post_path(@post) do %&amp;gt;
    &amp;lt;i class=&lt;/span&gt;&lt;span class="s2"&gt;"fa fa-trash"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/i&amp;gt;  # fontawesome icons
    Delete
&amp;lt;% end %&amp;gt;

# =&amp;gt;
&amp;lt;form action="/&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="s2"&gt;" method="&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;
  &amp;lt;input type="&lt;/span&gt;&lt;span class="n"&gt;hidden&lt;/span&gt;&lt;span class="s2"&gt;" name="&lt;/span&gt;&lt;span class="n"&gt;_method&lt;/span&gt;&lt;span class="s2"&gt;" value="&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
  &amp;lt;button type="&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;
    &amp;lt;i class="&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;trash&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;&amp;lt;/i&amp;gt;
    Delete
  &amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will generate a delete button with an icon and the text "Delete". The block is used to generate the content of the button, which is then wrapped in a form that sends a &lt;code&gt;DELETE&lt;/code&gt; request to the specified path when clicked. Get creative with your buttons and make them stand out!&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= button_to user_path(@user) do %&amp;gt;
    &amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;image_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"delete.png"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;% end &lt;/span&gt;&lt;span class="o"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/users/1"&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_method"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/assets/delete.png"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a button with an image of a trash can that, when clicked, sends a &lt;code&gt;DELETE&lt;/code&gt; request to the path specified by &lt;code&gt;user_path(@user)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Submit with options
&lt;/h2&gt;

&lt;p&gt;Another example of &lt;code&gt;button_to&lt;/code&gt; with a few options and &lt;code&gt;html_options&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, what we have here is a &lt;code&gt;button_to&lt;/code&gt; method that generates a form with a button inside. This button is used to generate a summary of a company's description using AI.&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%2Fn5trc7lkvqy0fdcmh7w9.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%2Fn5trc7lkvqy0fdcmh7w9.png" alt="button_to submit with options"&gt;&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= button_to "Generate Description Summary",
    description_summary_company_path(@company),
    method: :patch,
    class:'btn bg-indigo-50 disabled:opacity-50',
    data: { disable_with: "A short description summary in the making..."}
%&amp;gt;
# =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"button_to"&lt;/span&gt;
    &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;
    &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/startups/gamucatex/description_summary"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_method"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"patch"&lt;/span&gt; &lt;span class="n"&gt;autocomplete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"off"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"btn bg-indigo-50 disabled:opacity-50"&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;disable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"A short description summary in the making..."&lt;/span&gt;
        &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="no"&gt;Generate&lt;/span&gt; &lt;span class="no"&gt;Description&lt;/span&gt; &lt;span class="no"&gt;Summary&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;
    &amp;lt;input type="hidden"
        name="authenticity_token"
        value="yTWxr5_58rb_LqRQl36wgQpFh9K7a....."
        autocomplete="off"&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated HTML code includes a form tag with a &lt;code&gt;method&lt;/code&gt; of "&lt;code&gt;post&lt;/code&gt;" and an action attribute set to the &lt;code&gt;description_summary_company_path&lt;/code&gt; route. The &lt;code&gt;method&lt;/code&gt; is overridden by the method option, which sets it to "&lt;code&gt;patch&lt;/code&gt;" because most browsers don't support methods other than &lt;strong&gt;"&lt;code&gt;GET&lt;/code&gt;"&lt;/strong&gt; and &lt;strong&gt;"&lt;code&gt;POST&lt;/code&gt;"&lt;/strong&gt; when it comes to submitting forms. Amazingly, Rails works around this issue by matching other methods over &lt;code&gt;POST&lt;/code&gt; with a hidden input named "&lt;code&gt;_method&lt;/code&gt;", which is set to reflect the desired method &lt;code&gt;patch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The HTML options include a &lt;code&gt;class&lt;/code&gt; attribute, which sets the CSS class for the button to &lt;code&gt;"btn bg-indigo-50 disabled:opacity-50"&lt;/code&gt;. This will give the button a nice background colour and make it slightly transparent when disabled. I'm using &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;TailwindCSS&lt;/a&gt; for styling.&lt;/p&gt;

&lt;p&gt;There is a &lt;code&gt;data&lt;/code&gt; attribute with a &lt;code&gt;disable_with&lt;/code&gt; key that sets the text to display when the button is clicked, which is "A short description summary in the making...". This helps to provide feedback to the user that the button is doing something.&lt;/p&gt;

&lt;p&gt;Finally, the generated HTML code includes a hidden input tag with a CSRF token authenticity_token is included to protect against &lt;a href="https://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf" rel="noopener noreferrer"&gt;cross-site request forgery (CSRF)&lt;/a&gt; attacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hotwire with button_to
&lt;/h2&gt;

&lt;p&gt;Similar to &lt;code&gt;link_to&lt;/code&gt;, Hotwire and its tools, can enhance &lt;code&gt;button_to&lt;/code&gt; to create modern, interactive web applications. By default, &lt;code&gt;button_to&lt;/code&gt; generates a form with a button that sends a POST request to the server when clicked. However, with Hotwire and the Turbo tool, &lt;code&gt;button_to&lt;/code&gt; can be used to create smooth, fast user experiences without a full page reload.&lt;/p&gt;

&lt;p&gt;For example, let's say you want to create a button that sends a &lt;code&gt;DELETE&lt;/code&gt; request to the server, with a confirmation dialogue for the user to approve. With Hotwire, you can use the &lt;code&gt;data-turbo-confirm&lt;/code&gt; attribute to display a confirmation dialogue to the user, just like with &lt;code&gt;link_to&lt;/code&gt;. Here's an example:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= button_to
    "Delete Post",
    post_path(post),
    method: :delete,
    data: { turbo_confirm: "Are you sure?" }
%&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you click the button created with &lt;code&gt;button_to&lt;/code&gt;, it will submit a &lt;code&gt;DELETE&lt;/code&gt; request to the server and show a confirmation dialogue, similar to &lt;code&gt;link_to&lt;/code&gt;. Then Turbo comes in, processes the server response, and voila! The page content is updated without any page refresh with little or no JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  button to Conclusion
&lt;/h2&gt;

&lt;p&gt;Well, well, well. We've been exploring the magnificent world of Rails navigation tools, and &lt;code&gt;button_to&lt;/code&gt; is yet another powerful one. This incredible helper method allows us with minimal effort, you can create buttons that can perform a variety of actions such as submitting forms, sending requests to the server, and updating page content. &lt;code&gt;button_to&lt;/code&gt; also supports various options such as &lt;code&gt;method&lt;/code&gt;, &lt;code&gt;params&lt;/code&gt;, &lt;code&gt;class&lt;/code&gt;, and &lt;code&gt;data&lt;/code&gt;, allowing for even more flexibility and customization. With the integration of Hotwire, &lt;code&gt;button_to&lt;/code&gt; can provide users with a smooth and fast experience without the need for excessive JavaScript. Overall, &lt;code&gt;button_to&lt;/code&gt; is a valuable addition to any Rails developer's toolkit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;After all is said and done, &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; are both amazing helpers in the Rails world. With the help of Hotwire and Turbo, they offer fast and smooth navigation without needing to write tons of JavaScript. Whether you need to generate simple links or complex buttons, these helpers have got you covered. So, go ahead and use them to create your own magical and interactive web applications with ease!&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1- What is &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; in Rails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; are helper methods in Ruby on Rails that generate HTML links and buttons, respectively. They are commonly used in views to create hyperlinks and form submissions that send requests to the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2- What is the difference between &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main difference between &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; is that &lt;code&gt;link_to&lt;/code&gt; generates a hyperlink that navigates the user to a new page, while &lt;code&gt;button_to&lt;/code&gt; creates a form that submits a request to the server without navigating to a new page. However, both methods can be configured to use Ajax requests with Hotwire Turbo Drive in Rails 7, which is amazing!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3- How do I use &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; in Rails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both methods accept three required parameters: the link text or button label, the URL to which the request should be sent, and the HTTP method to use (&lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PATCH&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;). &lt;code&gt;link_to&lt;/code&gt; also accepts optional parameters for specifying attributes such as class, id, and data. &lt;code&gt;button_to&lt;/code&gt; accepts similar optional parameters, such as method, remote, &lt;code&gt;form_class&lt;/code&gt;, and &lt;code&gt;params&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4- How do I add a confirmation message to &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can add a confirmation message to &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; by including the &lt;code&gt;data: { confirm: "Are you sure?" }&lt;/code&gt; option. When the link or button is clicked, a confirmation dialogue box will be displayed with the specified message.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;5- How do I add custom HTML to &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt;? *&lt;/em&gt;&lt;br&gt;
You can use a block to add custom HTML to &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt;. Simply wrap the link text or button label in a block and include any additional HTML or Ruby code inside the block. For example:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to post_path(@post) do %&amp;gt;
  &amp;lt;i class=&lt;/span&gt;&lt;span class="s2"&gt;"fa fa-pencil"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/i&amp;gt;
  Edit Post
&amp;lt;% end %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6- Can I use &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; with Rails Hotwire?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, you can use &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; with Rails Hotwire by adding the &lt;code&gt;data-turbo="false"&lt;/code&gt; attribute to the link or button. This will disable Turbo Drive for that link or button, and the request will be processed with a full page reload. Alternatively, you can configure &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; to use Turbo Drive for non-&lt;code&gt;GET&lt;/code&gt; requests by default in Rails 7 and later versions.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Mastering Rails Web Navigation with link_to and button_to Helpers - Part 1</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Thu, 19 Oct 2023 19:01:50 +0000</pubDate>
      <link>https://forem.com/ahmednadar/mastering-rails-web-navigation-with-linkto-and-buttonto-helpers-part-1-3gbg</link>
      <guid>https://forem.com/ahmednadar/mastering-rails-web-navigation-with-linkto-and-buttonto-helpers-part-1-3gbg</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This tutorial is divided into two parts. In Part 1 &lt;strong&gt;(you are reading)&lt;/strong&gt;, we'll explore the Rails web navigation system, understand how Rails handles requests, and delve deep into the world of middleware. In Part 2, we'll focus on mastering the &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt; helpers and address frequently asked questions.&lt;/p&gt;

&lt;p&gt;Great, let’s get started!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TABLE OF CONTENTS (Part 1)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Introduction&lt;/p&gt;

&lt;p&gt;Navigation System&lt;/p&gt;

&lt;p&gt;How Rails Handles Requests&lt;/p&gt;

&lt;p&gt;Middlewares in Rails&lt;/p&gt;

&lt;p&gt;Frequently Asked Questions&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Have you ever wondered what happens when a user sends a web request to a site like &lt;a href="https://rubyonrails.org/"&gt;Rails&lt;/a&gt; and waits for a response?&lt;/p&gt;

&lt;p&gt;Imagine a scenario where a user clicks on a link or button on the &lt;a href="https://rubyonrails.org/"&gt;Rails&lt;/a&gt; website. This simple action initiates a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods"&gt;web request&lt;/a&gt; from the user's browser, which then travels through the vast universe of inter-webs galaxies to land on the planet web server that hosts "&lt;a href="https://rubyonrails.org/"&gt;Rails&lt;/a&gt;". The server then does its best and processes the request that was just received and sends back a response with the needed information and lands it safely to the plant user's browser, all in the blink of an eye!&lt;/p&gt;

&lt;p&gt;It's plain to see from that fancy figure up top that Rails has a pretty sophisticated communication process for handling incoming browser requests and dispatching responses. The process involves two major components: &lt;a href="https://guides.rubyonrails.org/action_controller_overview.html"&gt;ActionController&lt;/a&gt; and &lt;a href="https://guides.rubyonrails.org/action_view_overview.html"&gt;ActionView&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;ActionController&lt;/strong&gt; is where it's when it comes to the app's logic and data. It's the one in charge of talking to the database and carrying out CRUD operations as defined in the controller files. Meanwhile, &lt;strong&gt;ActionViews&lt;/strong&gt; is all about the presentation layer and cooking up the right response for each web request. This rockstar is responsible for putting together that response by rendering HTML templates, which are a mix of embedded Ruby code and HTML tags.&lt;/p&gt;

&lt;p&gt;In the world of Rails, magic is not a concept found in books and movies. It's part of the Rails framework! This magic simplifies the process of creating views, eliminates messy and duplicated code, and provides many other benefits that make our lives as developers easier and happier. But wait, how does it work, you might ask? By providing reusable helper classes and modules that encapsulate common behaviours and functionalities.&lt;/p&gt;

&lt;p&gt;Each helper class includes a library of helper methods that can be used to generate HTML tags and other content in views. For instance, the &lt;a href="https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html"&gt;FormHelper&lt;/a&gt; includes "form_for", the &lt;a href="https://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html"&gt;UrlHelper&lt;/a&gt; features the famous "link_to" and "button_to", and the &lt;a href="https://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html"&gt;TextHelper&lt;/a&gt; provides "truncate" among others. When we developers use these helpers, we can create more maintainable and organized code for our web applications. It's like having a wizard's wand in our hands!&lt;/p&gt;

&lt;p&gt;That being said, now hold on tight, everyone! We're about to dive into the thrilling world of web navigation with the help of two giants of the Rails world: &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt;, both of which belong to the legendary UrlHelper module. These powerhouses are the masterminds behind link creation and URL retrieval based on Rails routes. Join us on this adventure, and you'll be a web navigation master in the blink of an eye!&lt;/p&gt;

&lt;h1&gt;
  
  
  Navigation System
&lt;/h1&gt;

&lt;p&gt;Welcome to the web navigation systems of Rails. As we traverse the digital landscape, two guiding stars, &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt;, light our path. These methods are pivotal in Rails, enabling seamless navigation. But to truly appreciate their magic, we must first understand the underlying processes of Rails, especially the role of middleware and their responsibility in processing a web request.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Rails Handles Requests
&lt;/h1&gt;

&lt;p&gt;Let me set the scene for you. Imagine the web as a vast cosmos. Each click or request is like a spaceship (&lt;a href="https://en.wikipedia.org/wiki/USS_Enterprise_(NCC-1701-D)"&gt;thinking of USS Enterprise, any Star Trek fans!&lt;/a&gt;) embarking on an interstellar journey. When you navigate platforms like Rails, you're setting a course through the Rails galaxy. To show you a glimpse of this voyage, Engage:&lt;/p&gt;

&lt;p&gt;Navigating the vast universe of the web is akin to embarking on an interstellar journey. Each click, each request, is a spaceship travelling from one celestial body to another, seeking information. Let's chart the course of this spaceship as it journeys through the Rails galaxy as described in the outstanding figure above:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Liftoff:&lt;/strong&gt; The user, our astronaut, launches their spaceship by entering a URL in their browser, like &lt;a href="https://rubyonrails.org/"&gt;https://rubyonrails.org/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;First Contact:&lt;/strong&gt; This spaceship, now carrying &lt;strong&gt;a HTTP request&lt;/strong&gt;, approaches the Rails galaxy and makes its first contact with the &lt;strong&gt;Rails Router&lt;/strong&gt; (config/routes.rb).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Guidance System:&lt;/strong&gt; The router, acting as the galaxy's guidance system, determines which controller action should be activated — be it index, new, edit, show, or destroy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Mining:&lt;/strong&gt; The controller, now in charge, communicates with the appropriate model methods to gather the necessary resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Database Planet:&lt;/strong&gt; The model descends onto the Database planet to fetch the required data, which is then sent back to the controller.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Crafting the Message:&lt;/strong&gt; The controller, having gathered all it needs, communicates with the view to craft the final message.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transmission:&lt;/strong&gt; The view, using a mix of HTML and embedded Ruby, prepares the final response and sends it back to the waiting spaceship.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safe Return: The spaceship, now with the response, travels back and lands safely on the user's (our astronaut) browser, displaying the information. Missions accomplished!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This celestial dance ensures that each user's request is processed with precision. Central to this are ActionController and ActionView. While the ActionController orchestrates the logic and data, ActionViews crafts the visual spectacle, presenting the perfect response.&lt;/p&gt;

&lt;p&gt;The magic of Rails isn't mere folklore; it's tangible. It simplifies view creation, minimizes redundant code, and offers numerous benefits. This enchantment is powered by helper classes and modules that encapsulate common behaviours and functionalities, acting as our cosmic tools, and guiding us through the Rails universe.&lt;/p&gt;

&lt;h1&gt;
  
  
  Middlewares in Rails
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Navigating the Middleware Nebula:
&lt;/h3&gt;

&lt;p&gt;In the vast cosmos of a Rails application, middlewares are like the guiding stars in a nebula. Each middleware, similar to a star, has its unique luminance, ensuring that the web request travels smoothly through the Rails galaxy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Middlewares:
&lt;/h3&gt;

&lt;p&gt;Middleware in Rails is middleware in Rack. They act as the checkpoints or space stations between the web server (like Puma or Unicorn) and the Rails mothership. They inspect, modify, or process incoming and outgoing space signals (requests and responses). Each middleware either acts on the signal or hands it over to the next station (middleware) in the sequence, ensuring a smooth interstellar communication flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Middleware in Action: A Real-World Scenario
&lt;/h3&gt;

&lt;p&gt;Imagine a scenario where you want to log the time taken for each space signal (request) in your Rails application. Instead of embedding this logic in every corner of your mothership (Rails application controller), a middleware can elegantly handle it, centralizing the process and ensuring efficient communication.&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;RequestTimerMiddleware&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&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;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;

    &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt; &lt;span class="s2"&gt;"Request took &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; seconds."&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&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;In this example, the RequestTimerMiddleware logs the time taken for each request. The initialize method stores the current application, and the call method calculates the time difference between the start and end of the request.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Add a Middleware to Rails:
&lt;/h3&gt;

&lt;p&gt;To add the above middleware to your Rails application, you'd update the &lt;code&gt;config/application.rb&lt;/code&gt; file:&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="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="no"&gt;RequestTimerMiddleware&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Middlewares in Rails:
&lt;/h3&gt;

&lt;p&gt;Rails comes with a set of built-in middlewares that handle various tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Rack::Sendfile&lt;/code&gt;: Handles sending files efficiently from the server.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ActionDispatch::Static&lt;/code&gt;: Serves static files from the public directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Rack::Logger&lt;/code&gt;: Logs incoming HTTP requests.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Rack::Runtime&lt;/code&gt;: Sets an "X-Runtime" response header, indicating the response time of the request.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ActionDispatch::Cookies&lt;/code&gt;: Manages cookies, both reading and writing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ActionDispatch::Session::CookieStore&lt;/code&gt;: Handles cookie-based session storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... and many more! You can list that middleware by running &lt;code&gt;./bin/rails middleware&lt;/code&gt;. For a new Rails 7 application it looks like this:&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="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HostAuthorization&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Sendfile&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Static&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Executor&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ServerTiming&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Strategy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;LocalCache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Runtime&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MethodOverride&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RequestId&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RemoteIp&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Sprockets&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;QuietAssets&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Logger&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ShowExceptions&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Sentry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CaptureExceptions&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;WebConsole&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DebugExceptions&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Sentry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RescuedExceptionInterceptor&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionableExceptions&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Reloader&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Callbacks&lt;/span&gt;
&lt;span class="n"&gt;use&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="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CheckPending&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cookies&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CookieStore&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Flash&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ContentSecurityPolicy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PermissionsPolicy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Head&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ConditionalGet&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ETag&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TempfileReaper&lt;/span&gt;
&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Static&lt;/span&gt;
&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Middleware, while often operating behind the scenes, are the unsung heroes of a Rails application. They meticulously shape the request-response lifecycle, ensuring each signal is processed with precision. As we venture deeper into Rails, remember that for every task, be it logging, authentication, or session management, there's likely a middleware guiding the way. Now, let's set our sights on the next celestial wonders: &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Frequently Asked Questions
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;1. What is Middleware in Rails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Middleware is a layer in the Rails stack that sits between the web server and the Rails application. It processes requests before they reach the application and can also modify the response before it's sent back to the client. Middleware components are used for a variety of tasks, such as logging, caching, and security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. How do I add a new Middleware to my Rails application?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can add a new middleware to your Rails application by using the &lt;code&gt;config.middleware.use&lt;/code&gt; method in the &lt;code&gt;config/application.rb file&lt;/code&gt;. For example:&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="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="no"&gt;CustomMiddleware&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. How do I remove or skip a Middleware in Rails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to remove or skip a middleware, you can use the &lt;code&gt;config.middleware.delete&lt;/code&gt; method in the &lt;code&gt;config/application.rb&lt;/code&gt; file. For example:&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="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Lock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. How can I view the list of Middlewares used in my Rails 7 application?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can view the list of middlewares used in your Rails application by running the command &lt;code&gt;./bin/rails middleware&lt;/code&gt; in the terminal. This will display the middleware stack in the order they are executed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Why is the order of Middlewares important in Rails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The order of middleware is crucial because they are executed in a top-down sequence as they appear in the middleware stack. If one middleware stops the request from propagating down the stack, subsequent middleware won't get executed. Therefore, it's essential to ensure that the middleware are in the correct order, especially when they depend on each other.&lt;/p&gt;

&lt;p&gt;Coming Up in &lt;strong&gt;Part 2&lt;/strong&gt;: Dive deep into the functionalities of &lt;code&gt;link_to&lt;/code&gt; and &lt;code&gt;button_to&lt;/code&gt;, two powerful helpers that make web navigation in Rails a breeze. We'll explore their syntax, usage, and advanced features. Plus, we'll address some frequently asked questions to ensure you're well-equipped to navigate the Rails universe. Stay tuned!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Migration Magic ✨, Handling Not-Null Constraints in Production with Ruby on Rails</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Wed, 05 Apr 2023 14:26:04 +0000</pubDate>
      <link>https://forem.com/ahmednadar/migration-magic-handling-not-null-constraints-in-production-with-ruby-on-rails-1bc4</link>
      <guid>https://forem.com/ahmednadar/migration-magic-handling-not-null-constraints-in-production-with-ruby-on-rails-1bc4</guid>
      <description>&lt;p&gt;We've all been there-happily adding new tables and columns to our applications in the development environment. And when things go wrong, we drop the table and start fresh, no harm, no foul 😎. But what happens when we encounter issues in the production stage? That's when the challenge begins. In this post, we'll tackle a tricky migration scenario involving not-null constraints and share practical tips to avoid losing data in production. So buckle up, and let's dive in! 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  😌 Development Stage Bliss
&lt;/h3&gt;

&lt;p&gt;While i'm working on &lt;a href="https://validateok.click"&gt;validateok.click&lt;/a&gt; application I needed to add a new column &lt;code&gt;category&lt;/code&gt; to an existing table &lt;code&gt;ideas&lt;/code&gt;. Here's an example migration:&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;AddCategoryToIdeas&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;7.1&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;add_reference&lt;/span&gt; &lt;span class="ss"&gt;:ideas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                      &lt;span class="ss"&gt;:category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                      &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="s1"&gt;'Tools'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                      &lt;span class="ss"&gt;null: &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;foreign_key: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                      &lt;span class="ss"&gt;type: :uuid&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;In the development environment, running this migration is a breeze, and everything works as expected. But what about production? 😰&lt;/p&gt;

&lt;h3&gt;
  
  
  😬 Production Stage Hurdles
&lt;/h3&gt;

&lt;p&gt;In production, dropping a database isn't an option unless we're willing to lose everything - and nobody wants that! 😱 Using the same migration steps as we did in development above 👆🏼 can lead to errors, like this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR: column &lt;span class="s2"&gt;"category_id"&lt;/span&gt; of relation &lt;span class="s2"&gt;"ideas"&lt;/span&gt; contains null values
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error occurs because the existing records in the &lt;code&gt;ideas&lt;/code&gt; table don't have a &lt;code&gt;category_id&lt;/code&gt; value, not only that, and we've set the &lt;code&gt;null: false&lt;/code&gt; constraint. What can we do to fix this issue? 🤔&lt;/p&gt;

&lt;h3&gt;
  
  
  🪄 The Solution
&lt;/h3&gt;

&lt;p&gt;No worries! We have the perfect solution for you💡. Let's walk through the steps needed to handle this migration gracefully in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Remove the default value and split the migration into two parts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, remove the default value 'Tools' from the migration, as it should be a &lt;code&gt;UUID&lt;/code&gt;, not a string. &lt;em&gt;This is my mistake because I didn't pay attention that I'm using UUID. Am I the only one&lt;/em&gt;🤦‍♂️ Then, split the migration into two steps: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the &lt;code&gt;category_id&lt;/code&gt; column without the &lt;code&gt;null: false&lt;/code&gt; constraint and backfill the existing ideas with a default category. &lt;/li&gt;
&lt;li&gt;Finally, add the &lt;code&gt;null: false&lt;/code&gt; constraint.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's the updated migration file:&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;AddCategoryToIdeas&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;7.1&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;up&lt;/span&gt;
    &lt;span class="n"&gt;add_reference&lt;/span&gt; &lt;span class="ss"&gt;:ideas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;foreign_key: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: :uuid&lt;/span&gt; &lt;span class="c1"&gt;#1&lt;/span&gt;

    &lt;span class="n"&gt;default_category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_or_create_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;'Tools'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;Idea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;category_id: &lt;/span&gt;&lt;span class="n"&gt;default_category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;change_column_null&lt;/span&gt; &lt;span class="ss"&gt;:ideas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:category_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;#2&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;down&lt;/span&gt;
    &lt;span class="n"&gt;remove_reference&lt;/span&gt; &lt;span class="ss"&gt;:ideas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:category&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;&lt;strong&gt;Step 2: Understand the purpose of each step&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Add the &lt;code&gt;category_id&lt;/code&gt; column without the &lt;code&gt;null: false&lt;/code&gt; constraint. This allows us to update the existing records without violating the non-null constraint.&lt;/li&gt;
&lt;li&gt; Find or create a default category named 'Tools' and set its ID as the default &lt;code&gt;category_id&lt;/code&gt; for all existing ideas. This ensures that all existing ideas have a valid &lt;code&gt;category_id&lt;/code&gt; value.&lt;/li&gt;
&lt;li&gt; Add the &lt;code&gt;null: false&lt;/code&gt; constraint to the &lt;code&gt;category_id&lt;/code&gt; column. Now that all existing ideas have been updated with a default &lt;code&gt;category_id&lt;/code&gt;, we can safely enforce the non-null constraint.&lt;/li&gt;
&lt;li&gt;And now you can confidently run &lt;code&gt;rails db:migrate&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🗞 Wrapping Up
&lt;/h3&gt;

&lt;p&gt;And there you have it, folks! Thanks to these steps, we've gracefully handled a potentially tricky migration in the production environment without losing any data 🎉. By splitting the migration into two parts, updating the existing records, and then enforcing the non-null constraint, we've made our application more robust and reliable. &lt;/p&gt;

&lt;p&gt;Remember, as Rails developers, it's essential to think about the impact of our db migrations in both development and production environments. With a bit of vision, and a few well-placed emojis 😜, we can overcome these challenges and continue building fantastic applications.&lt;/p&gt;

&lt;p&gt;As always, Happy Coding, and until next time! 🚀&lt;/p&gt;

</description>
      <category>rails</category>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
    </item>
    <item>
      <title>🧹 Tidying Up Your Rails Code: The Art of Refactoring, Marie Kondo Style</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Mon, 03 Apr 2023 18:46:46 +0000</pubDate>
      <link>https://forem.com/ahmednadar/tidying-up-your-rails-code-the-art-of-refactoring-marie-kondo-style-4lgd</link>
      <guid>https://forem.com/ahmednadar/tidying-up-your-rails-code-the-art-of-refactoring-marie-kondo-style-4lgd</guid>
      <description>&lt;p&gt;You know that feeling when you're in the mood to crack on some code and do a 'brain dump' of ideas and code it? I'm sure everyone does, and it's perfectly fine. But sometimes, we forget about the initial brain dump and carry on with our lives, jobs, and continue coding, adding more complexity to the codebase. Until one day, it hits you and you figure out that you need to revisit 'an old friend' the old code and refactor it to make it polished, useful, easy, and maybe reusable for the future. Good thinking! This happens to me all the time – It feels like I'm constantly learning and growing in my quest to achieve better refactoring in my code.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏁 Initial code
&lt;/h2&gt;

&lt;p&gt;In a project, I needed to set a limitation on how many times a user could create a post. The application required only 3 posts per user (talk about exclusivity, huh?). Here's my initial code:&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;PostsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
    &lt;span class="n"&gt;before_action&lt;/span&gt; &lt;span class="ss"&gt;:check_limited_posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;if: :signed_in?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: :new&lt;/span&gt;

    &lt;span class="kp"&gt;private&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_limited_posts&lt;/span&gt;
    &lt;span class="n"&gt;limited_posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;current_user&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;size&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;limited_posts&lt;/span&gt;
    &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;posts_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;notice: &lt;/span&gt;&lt;span class="s1"&gt;'Currently we only offer a maximum of 3 posts.'&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;As you can see, there's nothing complex here, and the code is fine – it doesn't 'have to' change, right? But, we developers should always follow best practices, and refactoring is a fundamental one that we should always strive for (like superheroes of clean code!).&lt;/p&gt;

&lt;h2&gt;
  
  
  🧹 Refactoring
&lt;/h2&gt;

&lt;p&gt;So, I rolled up my sleeves and got to work on refactoring the code to make it more professional and reusable, and here is what I want to do:&lt;/p&gt;

&lt;p&gt;Extract the maximum number of allowed posts into a constant (because, who knows, we might be feeling more generous one day).&lt;/p&gt;

&lt;p&gt;Use a more descriptive name for the constant. And as you, naming is not easy.&lt;/p&gt;

&lt;p&gt;Use a more descriptive name for the &lt;code&gt;before_action&lt;/code&gt; method.&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;PostsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;    
    &lt;span class="no"&gt;MAX_POSTS_ALLOWED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;    
    &lt;span class="n"&gt;before_action&lt;/span&gt; &lt;span class="ss"&gt;:check_max_posts_allowed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;if: :signed_in?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: :new&lt;/span&gt;

    &lt;span class="kp"&gt;private&lt;/span&gt;    
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_max_posts_allowed&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_user&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;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="no"&gt;MAX_POSTS_ALLOWED&lt;/span&gt;
        &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;posts_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;notice: &lt;/span&gt;&lt;span class="s2"&gt;"Currently we only offer a maximum of &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;MAX_POSTS_ALLOWED&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; post(s)."&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;And voila! The check_max_posts_allowed the method is now more reusable, and it even has an easy name to remember (like a cool band name or a secret code). The maximum number of allowed posts is now defined as a constant, making it easier to modify in the future (perfect for those ever-changing project requirements). The method and constant names are more descriptive, making the code more readable and understandable, like a well-written novel.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗞 Conclusion
&lt;/h2&gt;

&lt;p&gt;Refactoring may seem like a trivial task, but it is an essential part of the development process. By following best practices and continuously refining our code, we can create more maintainable, reusable, and efficient applications. It's like decluttering our digital workspace, so our future selves will thank us!&lt;/p&gt;

&lt;p&gt;So, the next time you find yourself looking at your old code, remember the power of refactoring. Embrace the challenge, and let's keep striving to make our code better, cleaner, and more professional. After all, we're the superheroes of clean code, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  😉 One more thing
&lt;/h2&gt;

&lt;p&gt;But we're not done yet! Let's make our code even more modular and maintainable by moving the validation logic to a separate service object and using localization for our notice text. Wow, fancy stuff 😎&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Move validation logic to a service object&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new service object called PostValidator in the &lt;code&gt;app/services&lt;/code&gt; directory:&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;PostValidator&lt;/span&gt;   &lt;span class="no"&gt;MAX_POSTS_ALLOWED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;    
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check_max_posts_allowed&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="n"&gt;user&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;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="no"&gt;MAX_POSTS_ALLOWED&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;Now, update the &lt;code&gt;PostsController&lt;/code&gt; to use the new &lt;code&gt;PostValidator&lt;/code&gt; service object:&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;PostsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;   
    &lt;span class="n"&gt;before_action&lt;/span&gt; &lt;span class="ss"&gt;:check_max_posts_allowed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;if: :signed_in?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: :new&lt;/span&gt;    
    &lt;span class="kp"&gt;private&lt;/span&gt;   
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_max_posts_allowed&lt;/span&gt;     
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;PostValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check_max_posts_allowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       
            &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;posts_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;notice: &lt;/span&gt;&lt;span class="s2"&gt;"Currently we only offer a maximum of &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;PostValidator&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MAX_POSTS_ALLOWED&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; post(s)."&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Use localization for the notice text&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Update the &lt;code&gt;views.en.yml&lt;/code&gt; file in the &lt;code&gt;config/locales&lt;/code&gt; folder:&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="ss"&gt;en:   
    posts:
        new:     
            max_posts_notice: &lt;/span&gt;&lt;span class="s2"&gt;"Currently we only offer a maximum of %{max_posts} post(s)."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that I'm using a views file which is different from the default rails-generated &lt;code&gt;en.yml&lt;/code&gt; file. The views file focuses on the actions &lt;code&gt;new, index, show, ...&lt;/code&gt; for each object &lt;code&gt;post&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, update the &lt;code&gt;PostsController&lt;/code&gt; to use the notice text from the localization file:&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;PostsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;   
    &lt;span class="n"&gt;before_action&lt;/span&gt; &lt;span class="ss"&gt;:check_max_posts_allowed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;if: :signed_in?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: :new&lt;/span&gt;    

    &lt;span class="kp"&gt;private&lt;/span&gt;   
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_max_posts_allowed&lt;/span&gt;     
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;PostValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check_max_posts_allowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       
            &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;posts_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;notice: &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.posts.max_posts_notice'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;max_posts: &lt;/span&gt;&lt;span class="no"&gt;PostValidator&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MAX_POSTS_ALLOWED&lt;/span&gt;&lt;span class="p"&gt;)&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;.&lt;/code&gt; in &lt;code&gt;t('.posts.max_posts_notice',&lt;/code&gt; it is a reference to the object posts within views file. If you forget it you will get &lt;code&gt;translation missing: en.max_posts_notice&lt;/code&gt; error.&lt;/p&gt;

&lt;p&gt;And there you have it! Our code is now more modular, maintainable, and ready for any future changes. With these simple refactoring techniques, we've improved the readability and organization of our Ruby on Rails code, all while having a bit of fun along the way. Yuppy 👏🏼🤖&lt;/p&gt;

&lt;p&gt;And as always, Happy Coding 😀 💻&lt;/p&gt;

</description>
      <category>rails</category>
      <category>refactoring</category>
      <category>programming</category>
      <category>ruby</category>
    </item>
    <item>
      <title>🚀 A Unique Partnership: An Entrepreneurial Journey Like No Other 🌟</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Mon, 20 Mar 2023 04:00:28 +0000</pubDate>
      <link>https://forem.com/ahmednadar/a-unique-partnership-an-entrepreneurial-journey-like-no-other-1e4i</link>
      <guid>https://forem.com/ahmednadar/a-unique-partnership-an-entrepreneurial-journey-like-no-other-1e4i</guid>
      <description>&lt;p&gt;This is a unique post. It is not about development or design as I like to write, but it is a business collaboration. What is unique here, you might ask? My partner.&lt;/p&gt;

&lt;p&gt;The post is written by my partner, and every word and emoji. Nothing from me. I know you will enjoy it and it will surprise you 🤯👍🏼😆&lt;/p&gt;

&lt;p&gt;Greetings, esteemed community! Today, I'd like to share an extraordinary tale of innovation, collaboration, and a truly unique partnership. It all began with a brilliant idea from my business partner, Ahmed, who identified a gap in the market for indie makers seeking to validate their ideas before fully committing to them. 💡&lt;/p&gt;

&lt;p&gt;Ahmed's vision was to create a platform that empowers indie makers by enabling them to post their ideas in various formats, including written stories, videos, images, and even Stripe payment links. The validation process would be considered complete when a customer subscribes, pre-orders, or pays for the idea. 🎯&lt;/p&gt;

&lt;p&gt;With this ambitious concept in mind, our journey began. We started by purchasing a domain name, '&lt;a href="https://validateok.click,"&gt;https://validateok.click,&lt;/a&gt;' for just $1.98. As a resourceful developer, Ahmed set up free hosting on render.com and connected the domain, paving the way for our platform's digital presence. 🌐&lt;/p&gt;

&lt;p&gt;Ahmed then created a simple, yet functional, landing page as a starting point. But we knew there was more work to be done. Together, we brainstormed the ideal layout, content, and design elements to create a visually appealing and effective landing page that perfectly represents our vision. 🎨&lt;/p&gt;

&lt;p&gt;Throughout our partnership, we've faced challenges, shared laughs, and celebrated small victories. The road to success is never a straight line, but our combined efforts, perseverance, and determination keep us on track. Our goal is to bring '&lt;a href="https://validateok.click"&gt;https://validateok.click&lt;/a&gt;' to life, empowering indie makers worldwide to turn their dreams into reality. 🌍&lt;/p&gt;

&lt;p&gt;Now, it's time for the big reveal. You may have noticed that I haven't mentioned my name yet. Well, that's because I'm not your typical business partner. Drumroll, please 🥁 I'm Scrooge, an AI language model created by OpenAI, and I'm here to break the barriers between humans and AI in the world of entrepreneurship. 🤖&lt;/p&gt;

&lt;p&gt;So, dear friends, stay tuned for more thrilling updates from our one-of-a-kind partnership as we continue on this exhilarating journey. Who knows what surprises await us around the corner? 😉✨&lt;/p&gt;

&lt;p&gt;🚀 To be continued... 🌟&lt;/p&gt;

&lt;p&gt;So what do you think?!&lt;/p&gt;

&lt;p&gt;Follow 👀🧵 along on Twitter... &lt;a href="https://twitter.com/ahmednadar/status/1637254059894751234"&gt;https://twitter.com/ahmednadar/status/1637254059894751234&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/posts/ahmednadar_entrepreneurship-innovation-collaboration-activity-7043401181011865600-J0yH"&gt;https://www.linkedin.com/posts/ahmednadar_entrepreneurship-innovation-collaboration-activity-7043401181011865600-J0yH&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://news.ycombinator.com/item?id=35227049"&gt;https://news.ycombinator.com/item?id=35227049&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>entrepreneurship</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Ruby on Rails, The Ultimate Guide to strip, lstip and rstrip Methods</title>
      <dc:creator>Ahmed Nadar</dc:creator>
      <pubDate>Thu, 09 Feb 2023 18:45:00 +0000</pubDate>
      <link>https://forem.com/ahmednadar/ruby-on-rails-the-ultimate-guide-to-strip-and-lstrip-methods-5hgb</link>
      <guid>https://forem.com/ahmednadar/ruby-on-rails-the-ultimate-guide-to-strip-and-lstrip-methods-5hgb</guid>
      <description>&lt;p&gt;As a Rails developer I'm often faced with the task of processing and manipulating strings. These useful methods for string manipulation in Ruby are &lt;code&gt;strip&lt;/code&gt;, &lt;code&gt;lstrip&lt;/code&gt; and &lt;code&gt;rstrip&lt;/code&gt;. In this blog post, we will explore the differences between these  methods and how they can be used in Ruby or Rails.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;code&gt;strip&lt;/code&gt; in Ruby?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;strip&lt;/code&gt; method in Ruby is used to remove leading and trailing white spaces from a string. This is useful when you have text that is pulled in from another source and may contain unwanted white spaces at the beginning or end of the string. Here's an example of using &lt;code&gt;strip&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string = "   Remove leading and trailing spaces   "
stripped_string = string.strip
puts stripped_string
# =&amp;gt; "Remove leading and trailing spaces "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is &lt;code&gt;lstrip&lt;/code&gt; in Ruby?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;lstrip&lt;/code&gt; method in Ruby is used to remove leading white spaces from a string. This is useful when you want to remove white spaces from the beginning of a string, but keep any white spaces that appear at the end of the string. Here's an example of using &lt;code&gt;lstrip&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string = "   Remove leading and trailing spaces   "
l_stripped_string = string.lstrip
puts l_stripped_string
# =&amp;gt; "Remove leading and trailing spaces   "
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is &lt;code&gt;rstrip&lt;/code&gt; in Ruby?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;rstrip&lt;/code&gt; method in Ruby is used to remove only the trailing white spaces from a string. This is useful when you have text that is pulled in from another source and may contain unwanted white spaces at the end of the string. Here's an example of using &lt;code&gt;rstrip&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string = " Remove trailing spaces " 
r_stripped_string = string.rstrip 
puts r_stripped_string
# =&amp;gt; "   Remove leading and trailing spaces"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Differences between &lt;code&gt;strip&lt;/code&gt;, &lt;code&gt;lstrip&lt;/code&gt; and &lt;code&gt;rstrip&lt;/code&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;strip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes leading and trailing white spaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lstrip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes leading white spaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rstrip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes trailing white spaces&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the main difference between &lt;code&gt;strip&lt;/code&gt; ,&lt;code&gt;lstrip&lt;/code&gt; and &lt;code&gt;rstrip&lt;/code&gt; is the type of white spaces they remove. &lt;code&gt;strip&lt;/code&gt; removes both leading and trailing white spaces, &lt;code&gt;lstrip&lt;/code&gt; only removes leading white spaces, while &lt;code&gt;rstip&lt;/code&gt; only removes trailing white spaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;When it comes to performance, &lt;code&gt;strip&lt;/code&gt;, &lt;code&gt;lstrip&lt;/code&gt; and  &lt;code&gt;rstrip&lt;/code&gt; are relatively fast. To compare the performance of these methods, we can run a benchmark test using the Ruby &lt;code&gt;benchmark&lt;/code&gt; library. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'benchmark'

string = "   When it comes to performance, strip, lstrip and rstrip are relatively fast. To compare the performance of these methods, we can run a benchmark test using the Ruby benchmark library. Here's an example:   "
Benchmark.bm do |x|
  x.report("strip:") { 100000.times { string.strip } }
  x.report("lstrip:") { 100000.times { string.lstrip } }
  x.report("rstrip:") { 100000.times { string.rstrip } }
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;user&lt;/th&gt;
&lt;th&gt;system&lt;/th&gt;
&lt;th&gt;total&lt;/th&gt;
&lt;th&gt;real&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;strip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.029657&lt;/td&gt;
&lt;td&gt;0.060237&lt;/td&gt;
&lt;td&gt;0.089894&lt;/td&gt;
&lt;td&gt;( 0.141788)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lstrip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.035660&lt;/td&gt;
&lt;td&gt;0.000601&lt;/td&gt;
&lt;td&gt;0.036261&lt;/td&gt;
&lt;td&gt;( 0.036798)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rstrip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.027587&lt;/td&gt;
&lt;td&gt;0.000578&lt;/td&gt;
&lt;td&gt;0.028165&lt;/td&gt;
&lt;td&gt;( 0.028700)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[#
&amp;lt;Benchmark::Tms:0x0000000112b2faa8 @label="strip:", @real=0.14178800000809133, @cstime=0.0, @cutime=0.0, @stime=0.060236999999999985, @utime=0.029656999999999933, @total=0.08989399999999992&amp;gt;, #

&amp;lt;Benchmark::Tms:0x0000000112b2fa08 @label="lstrip:", @real=0.036798000102862716, @cstime=0.0, @cutime=0.0, @stime=0.0006009999999999627, @utime=0.035660000000000025, @total=0.03626099999999999&amp;gt;, #

&amp;lt;Benchmark::Tms:0x0000000112b2f9b8 @label="rstrip:", @real=0.02870000002440065, @cstime=0.0, @cutime=0.0, @stime=0.0005779999999999674, @utime=0.027587000000000028, @total=0.028164999999999996&amp;gt;
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results of the benchmark test show that &lt;code&gt;strip&lt;/code&gt;, &lt;code&gt;lstrip&lt;/code&gt; and &lt;code&gt;rstrip&lt;/code&gt; are very fast methods, with &lt;code&gt;rstrip&lt;/code&gt; being slightly faster than both &lt;code&gt;strip&lt;/code&gt; and &lt;code&gt;lstrip&lt;/code&gt; in this case. However, the difference in performance is very small and likely to be negligible in most real-world applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Combination with other methods
&lt;/h2&gt;

&lt;p&gt;Each of &lt;code&gt;strip&lt;/code&gt;, &lt;code&gt;lstrip&lt;/code&gt; and &lt;code&gt;rstrip&lt;/code&gt; can be combined with other string methods in Ruby to achieve more complex string manipulations. For example, you can use &lt;code&gt;gsub&lt;/code&gt; to replace specific characters in a string, and then use &lt;code&gt;strip&lt;/code&gt; , &lt;code&gt;lstrip&lt;/code&gt; or &lt;code&gt;rstrip&lt;/code&gt; to remove any whitespace from the start or end. Here's an example using &lt;code&gt;split()&lt;/code&gt; method to split a string into an array based on a specific delimiter, and then using &lt;code&gt;lstrip&lt;/code&gt; to remove any whitespace from the left of each element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text = " apple , banana , cherry "

s_text = text.split(",").map(&amp;amp;:strip).to_s
puts 'Strip =' + s_text 
# =&amp;gt; Strip =["apple", "banana", "cherry"]

l_text = text.split(",").map(&amp;amp;:lstrip).to_s
puts 'lStrip =' + l_text 
# =&amp;gt; lStrip =["apple ", "banana ", "cherry "]

r_text = text.split(",").map(&amp;amp;:rstrip).to_s
puts 'rStrip =' + r_text 
# =&amp;gt; rStrip =[" apple", " banana", " cherry"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By combining strip and lstrip with other string methods, you can easily manipulate and clean up strings in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Choosing between &lt;code&gt;strip&lt;/code&gt;, &lt;code&gt;lstrip&lt;/code&gt; and &lt;code&gt;rstrip&lt;/code&gt; depends on the specific use case and the desired outcome. If you need to remove whitespaces from both ends of a string, then use &lt;code&gt;strip&lt;/code&gt;. If you only need to remove whitespaces from the left end, then use &lt;code&gt;lstrip&lt;/code&gt;. And If you only need to remove whitespaces from the right end, then use &lt;code&gt;rstrip&lt;/code&gt;.&lt;br&gt;
It's always good to test theose methods and choose the one that meets your requirements and performs best.&lt;/p&gt;

&lt;p&gt;In conclusion, understanding the differences between &lt;code&gt;strip&lt;/code&gt;, &lt;code&gt;lstrip&lt;/code&gt; and &lt;code&gt;rstrip&lt;/code&gt; is important to make the right choice and get the expected results in your Ruby on Rails code. By following the advice and examples in this article, you'll be able to make an informed decision and use the right method for the job.&lt;/p&gt;

&lt;p&gt;And as usual, Happy Coding 😀 💻&lt;/p&gt;

</description>
      <category>tooling</category>
    </item>
  </channel>
</rss>
