<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arish Khan</title>
    <description>The latest articles on DEV Community by Arish Khan (@arish_khan_efd51766053f80).</description>
    <link>https://dev.to/arish_khan_efd51766053f80</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%2F2741704%2F743d637f-49ad-4af3-b57a-8a0c3709fe57.png</url>
      <title>DEV Community: Arish Khan</title>
      <link>https://dev.to/arish_khan_efd51766053f80</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arish_khan_efd51766053f80"/>
    <language>en</language>
    <item>
      <title>Exploring ActiveRecord::Base::normalizes in Rails 7.1</title>
      <dc:creator>Arish Khan</dc:creator>
      <pubDate>Wed, 22 Jan 2025 07:26:10 +0000</pubDate>
      <link>https://dev.to/arish_khan_efd51766053f80/exploring-activerecordbasenormalizes-in-rails-71-3825</link>
      <guid>https://dev.to/arish_khan_efd51766053f80/exploring-activerecordbasenormalizes-in-rails-71-3825</guid>
      <description>&lt;p&gt;Occasionally, there’s a need to standardize data before it’s stored in a database. For instance, you might want to convert email addresses to lowercase, eliminate leading and trailing spaces, and more. With the introduction of Rails 7.1, the new ActiveRecord::Base::normalizes API comes into play. This feature empowers you to normalize attribute values to a uniform format before they’re persisted in the database. By doing so, you enhance the integrity and consistency of your data and simplify the process of querying records based on attribute values&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Prior to Rails 7.1, attribute normalization could be achieved by utilizing the before_save callback.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="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;:normalize_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;normalize_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;if&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;present?&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;h1&gt;
  
  
  &lt;strong&gt;Rails 7.1 onwards&lt;/strong&gt;
&lt;/h1&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;downcase&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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, the normalization will not be applied to nil values. This behavior can be modified using the apply_to_nil option, which is set to false by default.&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;titleize&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;'example@yourdomain.com'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;apply_to_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;p&gt;You can also utilize the normalizes method to apply normalization to multiple attributes simultaneously.&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;:first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last_name&lt;/span&gt;&lt;span class="p"&gt;,&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;with: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;attribute&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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How can you apply normalization to pre-existing records?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Normalization takes effect when an attribute is assigned or updated. This implies that if a record was saved before the normalization rule was established, the attribute won’t be normalized until it receives a new value. To address this, you can explicitly perform migration through Normalization#normalize_attribute.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="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="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="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&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="k"&gt;end&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_each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# user.email # =&amp;gt; "\n\nexample@DOMAIN.COM\n"&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;normalize_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# user.email # =&amp;gt; "example@domain.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;save&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;Note:&lt;/strong&gt; The normalization can be applied multiple times and is designed to be idempotent. This means that applying the normalization repeatedly will yield the same result as applying it just once.&lt;/p&gt;

&lt;p&gt;Please review this &lt;a href="https://github.com/rails/rails/pull/43945" rel="noopener noreferrer"&gt;&lt;strong&gt;pull request&lt;/strong&gt;&lt;/a&gt; for more details.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>rails7</category>
      <category>activerecord</category>
    </item>
    <item>
      <title>Rails - 8 Authentication Generator</title>
      <dc:creator>Arish Khan</dc:creator>
      <pubDate>Tue, 21 Jan 2025 11:39:44 +0000</pubDate>
      <link>https://dev.to/arish_khan_efd51766053f80/rails-8-authentication-generator-154m</link>
      <guid>https://dev.to/arish_khan_efd51766053f80/rails-8-authentication-generator-154m</guid>
      <description>&lt;p&gt;Simplifying Authentication in Rails 8 with a New Generator&lt;/p&gt;

&lt;p&gt;With Rails 8, developers now have a straightforward way to add essential authentication features without relying on complex all-in-one gems. Rails now includes a built-in generator that brings together all the fundamental components needed for basic user authentication. This guide will walk you through the capabilities of this new authentication scaffold and explain how it can help streamline your Rails application setup.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Getting Started with Authentication in Rails 8&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To add a basic authentication system, you can run the following command in your Rails project:&lt;/p&gt;

&lt;p&gt;bin/rails generate authentication&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This command generates essential files that form the foundation for a complete authentication system, including session handling and password reset functionality. Let’s delve into the structure and details of what’s generated.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Models and Database Migrations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Certainly! Here’s a rephrased version that maintains the essential information but is presented with distinct wording and structure:&lt;/p&gt;




&lt;h3&gt;
  
  
  Simplifying Authentication in Rails 8 with a New Generator
&lt;/h3&gt;

&lt;p&gt;With Rails 8, developers now have a straightforward way to add essential authentication features without relying on complex all-in-one gems. Rails now includes a built-in generator that brings together all the fundamental components needed for basic user authentication. This guide will walk you through the capabilities of this new authentication scaffold and explain how it can help streamline your Rails application setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with Authentication in Rails 8
&lt;/h3&gt;

&lt;p&gt;To add a basic authentication system, you can run the following command in your Rails project:&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;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="n"&gt;authentication&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command generates essential files that form the foundation for a complete authentication system, including session handling and password reset functionality. Let’s delve into the structure and details of what’s generated.&lt;/p&gt;

&lt;h4&gt;
  
  
  Core Models and Database Migrations
&lt;/h4&gt;

&lt;p&gt;Rails sets up models and migrations to handle user accounts and session management, creating a solid foundation for authentication. Here are the key components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CreateUsers Migration&lt;/strong&gt;: This migration creates a &lt;code&gt;users&lt;/code&gt; table with an &lt;code&gt;email_address&lt;/code&gt; field that’s uniquely indexed and a &lt;code&gt;password_digest&lt;/code&gt; field for secure password storage using &lt;code&gt;has_secure_password&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CreateSessions Migration&lt;/strong&gt;: This migration defines a &lt;code&gt;sessions&lt;/code&gt; table with a &lt;code&gt;token&lt;/code&gt; field (ensuring uniqueness), along with fields for &lt;code&gt;ip_address&lt;/code&gt; and &lt;code&gt;user_agent&lt;/code&gt; to track the user’s device and network. The &lt;code&gt;Session&lt;/code&gt; model includes &lt;code&gt;has_secure_token&lt;/code&gt; for generating unique session tokens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Current Model&lt;/strong&gt;: This model manages per-request data and gives convenient access to the current user, using a &lt;code&gt;user&lt;/code&gt; method that delegates to the session.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;bcrypt&lt;/code&gt; gem, used for secure password handling, is added to your Gemfile if it’s not already there or commented out, and &lt;code&gt;bundle install&lt;/code&gt; is run to ensure it's available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication Concern: Core Logic
&lt;/h3&gt;

&lt;p&gt;The authentication flow is encapsulated within an &lt;code&gt;Authentication&lt;/code&gt; concern, which includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;require_authentication&lt;/strong&gt;: A &lt;code&gt;before_action&lt;/code&gt; that checks for an existing session using &lt;code&gt;resume_session&lt;/code&gt;. If none is found, it redirects the user to the login page via &lt;code&gt;request_authentication&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;resume_session&lt;/strong&gt;: Finds an existing session through a signed cookie token and sets it as the active session. It then saves this session token in a permanent, HTTP-only cookie with &lt;code&gt;set_current_session&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;authenticated?&lt;/strong&gt;: A helper that verifies if there’s an active session for the current user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;allow_unauthenticated_access&lt;/strong&gt;: A method that permits specific actions to bypass the &lt;code&gt;require_authentication&lt;/code&gt; check.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;start_new_session_for(user)&lt;/strong&gt;: Begins a new session for the specified user, recording the user’s device and IP address information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;terminate_session&lt;/strong&gt;: Ends the current session and removes its cookie token.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Managing Sessions with a Sessions Controller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;SessionsController&lt;/code&gt; facilitates user session handling with the following actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;new&lt;/strong&gt;: Presents a login form for user credentials. The &lt;code&gt;new.html.erb&lt;/code&gt; file offers fields for the user’s email and password, along with flash messages for errors or success, plus a link to reset the password if needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;create&lt;/strong&gt;: Authenticates the user based on provided credentials. Upon successful login, it starts a session and redirects to the &lt;code&gt;after_authentication_url&lt;/code&gt;; if credentials are incorrect, it redirects to the login form with an error message.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;destroy&lt;/strong&gt;: Ends the current session and sends the user back to the login page.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Password Reset Workflow
&lt;/h4&gt;

&lt;p&gt;The generator also provides a basic password reset feature, covering everything from initiating a reset request to updating a password. This functionality is managed by the &lt;code&gt;PasswordsController&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;new&lt;/strong&gt;: Displays a form for requesting a password reset.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;create&lt;/strong&gt;: Processes the reset request, sending an email with reset instructions if the user exists. The email includes a link with a &lt;code&gt;password_reset_token&lt;/code&gt;, which expires in 15 minutes by default, allowing access to the password reset page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;edit&lt;/strong&gt;: Shows a form where the user can input a new password.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;update&lt;/strong&gt;: Finalizes the password change, redirecting on success or showing an error on failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;set_user_by_token&lt;/strong&gt;: A &lt;code&gt;before_action&lt;/code&gt; callback for &lt;code&gt;edit&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; actions that identifies the user based on the reset token in the URL, ensuring secure reset handling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Limitations and Future Improvements
&lt;/h4&gt;

&lt;p&gt;Currently, the generator offers email-password login for existing users but doesn’t yet support user account creation. Additional customization options and features may come in future updates.&lt;/p&gt;

&lt;p&gt;To learn more about the implementation details, check out the following pull requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rails/rails/pull/52328" rel="noopener noreferrer"&gt;https://github.com/rails/rails/pull/52328&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rails/rails/pull/52472" rel="noopener noreferrer"&gt;https://github.com/rails/rails/pull/52472&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rails/rails/pull/52483" rel="noopener noreferrer"&gt;https://github.com/rails/rails/pull/52483&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Know more about the Topic and me:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Portfolio: &lt;a href="https://www.arishdev.com" rel="noopener noreferrer"&gt;https://www.arishdev.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code: &lt;a href="https://github.com/Arish-Dev-Academy/rails-8-authentication" rel="noopener noreferrer"&gt;https://github.com/Arish-Dev-Academy/rails-8-authentication&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Video: &lt;a href="https://youtu.be/Boi_9amq_eg?si=QfirKgGFLgm_QK9Z" rel="noopener noreferrer"&gt;https://youtu.be/Boi_9amq_eg?si=QfirKgGFLgm_QK9Z&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rails</category>
      <category>authentication</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
