<?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: Santanu Bhattacharya</title>
    <description>The latest articles on DEV Community by Santanu Bhattacharya (@santattech).</description>
    <link>https://dev.to/santattech</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%2F1078503%2F68041fc9-f94d-43d4-a8b9-5fbad2d1abec.jpg</url>
      <title>DEV Community: Santanu Bhattacharya</title>
      <link>https://dev.to/santattech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/santattech"/>
    <language>en</language>
    <item>
      <title>Check my latest post on how we debug the JRuby with Weblogic, and restore the application from crashing to working.
#jruby #weblogic #programing</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Fri, 20 Feb 2026 08:05:22 +0000</pubDate>
      <link>https://dev.to/santattech/check-my-latest-post-on-how-we-debug-the-jruby-with-weblogic-and-restore-the-application-from-28fl</link>
      <guid>https://dev.to/santattech/check-my-latest-post-on-how-we-debug-the-jruby-with-weblogic-and-restore-the-application-from-28fl</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/santattech" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1078503%2F68041fc9-f94d-43d4-a8b9-5fbad2d1abec.jpg" alt="santattech"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/santattech/from-jruby-weblogic-panic-to-peace-a-debugging-story-1k3" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;🧵 From JRuby + WebLogic Panic to Peace: A Debugging Story&lt;/h2&gt;
      &lt;h3&gt;Santanu Bhattacharya ・ Feb 20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#devjournal&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#git&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#java&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ruby&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>jruby</category>
      <category>java</category>
      <category>weblogic</category>
      <category>web</category>
    </item>
    <item>
      <title>🧵 From JRuby + WebLogic Panic to Peace: A Debugging Story</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Fri, 20 Feb 2026 07:47:31 +0000</pubDate>
      <link>https://dev.to/santattech/from-jruby-weblogic-panic-to-peace-a-debugging-story-1k3</link>
      <guid>https://dev.to/santattech/from-jruby-weblogic-panic-to-peace-a-debugging-story-1k3</guid>
      <description>&lt;h2&gt;
  
  
  How a tiny git: in Gemfile, cache broke our WAR deployment — and cost me a sleepless night.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  😰 The Situation
&lt;/h2&gt;

&lt;p&gt;We have multiple JRuby applications deployed on Oracle WebLogic.&lt;br&gt;
One of them suddenly stopped working.&lt;/p&gt;

&lt;p&gt;It had been:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Working in production&lt;/li&gt;
&lt;li&gt;✅ Working earlier on this same server&lt;/li&gt;
&lt;li&gt;❌ Suddenly failing during startup
The error:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;org.jruby.exceptions.StandardError:
(GitError) https://github.com/jruby/warbler (at master@973d14c)
is not yet checked out. Run `bundle install` first.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And not just one error, And not just one error.&lt;br&gt;
Multiple layers of errors.&lt;br&gt;
That’s when the tension started.&lt;/p&gt;
&lt;h3&gt;
  
  
  🥊 Phase 1: Class Conflict Error
&lt;/h3&gt;

&lt;p&gt;The first error looked like a classic classloader issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;undefined method `bytesize' for Rack::Utils:Module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s usually a symptom of:&lt;br&gt;
Different Rack versions loaded&lt;br&gt;
Library collision&lt;br&gt;
Parent-first classloading override&lt;/p&gt;

&lt;p&gt;We had:&lt;br&gt;
Multiple JRuby apps in the same WebLogic domain&lt;br&gt;
Different JRuby versions (The other app is using 9.3.5.0 and this one 9.4.5.0)&lt;br&gt;
Different Rack versions&lt;br&gt;
WebLogic loads classes parent-first by default.&lt;br&gt;
That means server-level classes may override WAR classes.&lt;br&gt;
So if another JRuby app loads Rack first…&lt;br&gt;
You’re in trouble.&lt;/p&gt;

&lt;p&gt;One solution is, we can downgrade the application to 9.3.5.0 and try redeploying to check if it works. But at first, I don't want to downgrade the application as earlier I have spent a lot to upgrade this application.&lt;/p&gt;
&lt;h3&gt;
  
  
  Fix Attempt #1 — weblogic.xml Change
&lt;/h3&gt;

&lt;p&gt;Since we have other Jruby applications in other managed server. When we compare the weblogic.xml, it has different content than what I maintained earlier. So I bring that part of the xml here as well. &lt;/p&gt;

&lt;p&gt;We updated weblogic.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;weblogic-web-app&amp;gt;
  &amp;lt;container-descriptor&amp;gt;
    &amp;lt;prefer-web-inf-classes&amp;gt;true&amp;lt;/prefer-web-inf-classes&amp;gt;
  &amp;lt;/container-descriptor&amp;gt;
&amp;lt;/weblogic-web-app&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells WebLogic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load classes from the WAR first.&lt;/li&gt;
&lt;li&gt;Since the other application's JRuby version is different, it somehow still gives the same error after deployment. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, I found that the jar file of the application is still different in the WebLogic log. And the application is failing at the weblogic level. The application log has not been hit yet. &lt;/p&gt;

&lt;p&gt;I cross check the Gemfile.lock and found it is different than 9.4.5.0. So, I decided to update that to same 9.4.5.0.&lt;br&gt;
&lt;strong&gt;But how the application was working early in weblogic?&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Too Many Deployments
&lt;/h3&gt;

&lt;p&gt;If you have multiple versions of WAR deployed (including old ones not yet undeployed), WebLogic validates all of them before displaying the UI. So I decided to clean the cache if there is any in WebLogic.&lt;/p&gt;

&lt;p&gt;Fix:&lt;br&gt;
I have found the cache and tmp directories.&lt;br&gt;
Clean staging directory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$DOMAIN_HOME/servers/AdminServer/tmp&lt;/li&gt;
&lt;li&gt;$DOMAIN_HOME/servers/AdminServer/cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Stop server first)&lt;br&gt;
After deploying with this change:&lt;br&gt;
✅ The class conflict error disappeared.&lt;br&gt;
Relief?&lt;br&gt;
Not yet.&lt;br&gt;
Because something worse appeared.&lt;/p&gt;
&lt;h3&gt;
  
  
  💥 Phase 2: The Git/Bundler Explosion
&lt;/h3&gt;

&lt;p&gt;Now the error became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(GitError) https://github.com/jruby/warbler (at master@973d14c)
is not yet checked out. Run `bundle install` first.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which makes zero sense in production.&lt;/p&gt;

&lt;p&gt;You don’t run bundle install inside a deployed WAR.&lt;br&gt;
WAR files should be fully packaged artifacts.&lt;br&gt;
So why was Bundler complaining?&lt;/p&gt;

&lt;p&gt;The Real Clue: Expanding the WAR&lt;/p&gt;

&lt;p&gt;I extracted the WAR:&lt;br&gt;
&lt;code&gt;jar xf myapp.war&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inside:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/WEB-INF/gems/bundler/gems/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I saw:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;warbler-973d14c8f7e3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That suffix (973d14c8f7e3) means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Warbler was installed from Git.&lt;br&gt;
And then I checked our &lt;code&gt;Gemfile&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Actual Root Cause&lt;/p&gt;

&lt;p&gt;We had this in Gemfile:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gem 'warbler', '2.0.5', git: 'https://github.com/jruby/warbler', branch: 'master', platforms: :jruby&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;p&gt;Warbler was pinned to a Git commit&lt;br&gt;
Bundler stored commit metadata&lt;br&gt;
The WAR expected a git checkout&lt;/p&gt;

&lt;p&gt;But in WebLogic:&lt;/p&gt;

&lt;p&gt;No .git&lt;br&gt;
No working tree&lt;br&gt;
No git context&lt;br&gt;
So Bundler threw:&lt;br&gt;
is not yet checked out&lt;br&gt;
It worked before because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cached bundle&lt;/li&gt;
&lt;li&gt;Slightly different build state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it was fragile.&lt;br&gt;
And eventually, it broke.&lt;br&gt;
I checked in web and found that they are suggesting to use the gem from the rubygems.org instead of git. My other applications are working fine. So I decided to keep it simple and pull from github only.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅ The Correct Fix
&lt;/h3&gt;

&lt;p&gt;The WAR contained:&lt;br&gt;
/WEB-INF/gems/bundler/gems/warbler-973d14c8f7e3&lt;/p&gt;

&lt;p&gt;That commit hash indicated:&lt;br&gt;
Bundler had cached a git checkout&lt;/p&gt;

&lt;p&gt;The artifact embedded metadata tied to a specific commit&lt;br&gt;
Something in that cached state became inconsistent&lt;/p&gt;

&lt;p&gt;Because I wasn’t rebuilding with a clean bundle, the WAR kept packaging a partially cached or inconsistent git state.&lt;br&gt;
The real solution was:&lt;/p&gt;

&lt;p&gt;Use the github commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem 'warbler', git: 'https://github.com/jruby/warbler.git', ref: '93d14c'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then rebuild clean:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bundle install --no-cache&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That forced Bundler to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Re-fetch the git repository&lt;/li&gt;
&lt;li&gt;Re-resolve dependencies&lt;/li&gt;
&lt;li&gt;Remove stale metadata
Rebuild cleanly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;RAILS_ENV=production bundle exec jruby -S warble --trace&lt;/code&gt;&lt;br&gt;
Also this time, I restarted the weblogic service from the server entirely.&lt;br&gt;
Redeploy.&lt;/p&gt;

&lt;p&gt;Everything worked.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Actually Happened
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Classloader conflict caused Rack error&lt;/li&gt;
&lt;li&gt;Fixed via prefer-web-inf-classes&lt;/li&gt;
&lt;li&gt;That exposed a git-based Warbler inconsistency&lt;/li&gt;
&lt;li&gt;Cached bundle state caused broken WAR packaging&lt;/li&gt;
&lt;li&gt;bundle install --no-cache cleaned it&lt;/li&gt;
&lt;li&gt;Rebuild fixed everything&lt;/li&gt;
&lt;li&gt;This wasn’t a single bug.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It was layered:&lt;br&gt;
Server classloading&lt;br&gt;
Git-based gem&lt;br&gt;
Bundler caching behavior&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>java</category>
      <category>ruby</category>
      <category>weblogic</category>
    </item>
    <item>
      <title>🚀 Using Tomcat for Blazing-Fast JRuby WAR Testing</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Thu, 02 Oct 2025 12:44:50 +0000</pubDate>
      <link>https://dev.to/santattech/using-tomcat-for-blazing-fast-jruby-war-testing-m9o</link>
      <guid>https://dev.to/santattech/using-tomcat-for-blazing-fast-jruby-war-testing-m9o</guid>
      <description>&lt;p&gt;Recently, while contributing to a JRuby pull request (&lt;a href="https://github.com/jruby/warbler/pull/572" rel="noopener noreferrer"&gt;https://github.com/jruby/warbler/pull/572&lt;/a&gt; on warbler), I was reminded of a classic piece of IT infrastructure: Tomcat. It's a common term, sure, but as a developer focused on rapid Ruby development and often dreading heavyweight deployments, I hadn't touched it in ages.&lt;/p&gt;

&lt;p&gt;If you've ever had to quickly iterate on a JRuby WAR file—the kind that packages your Ruby application to run on a Weblogic —you know the pain. It is very powerful, but heavy and opinionated. The installation is complex.&lt;/p&gt;

&lt;p&gt;This is where the lightweight champion, Apache Tomcat, comes in. It's the perfect environment for quick testing, R&amp;amp;D, and prototyping. Let's see how you can set it up locally in minutes for your JRuby testing needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Tomcat?
&lt;/h2&gt;

&lt;p&gt;Apache Tomcat is an open-source Java servlet container.&lt;/p&gt;

&lt;p&gt;Crucially, it is not a full-fledged Java EE Application Server (like WebLogic, JBoss/WildFly, or GlassFish). This is the key to its speed and simplicity.&lt;/p&gt;

&lt;p&gt;Tomcat specializes in running:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Servlets (Java server-side programs)&lt;/li&gt;
&lt;li&gt;JSP (JavaServer Pages)&lt;/li&gt;
&lt;li&gt;WAR files (Web ARchives, packaged in a standard WEB-INF format)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting Up Tomcat Locally for WAR Deployment
&lt;/h3&gt;

&lt;p&gt;If you are on Ubuntu, getting Tomcat ready is incredibly fast. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installation and Service Control
The easiest way to install:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install tomcat9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, you can manage the service with standard systemctl commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action    Command&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A. Stop:    &lt;code&gt;sudo systemctl stop tomcat9&lt;/code&gt;&lt;br&gt;
B. Start:   &lt;code&gt;sudo systemctl start tomcat9&lt;/code&gt;&lt;br&gt;
C. Restart: &lt;code&gt;sudo systemctl restart tomcat9&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Key Folder Structure
&lt;/h3&gt;

&lt;p&gt;For a typical Ubuntu install, the core directory is &lt;code&gt;/var/lib/tomcat9&lt;/code&gt;. Knowing these folders is essential for manual deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;webapps/ → This is where you drop your WAR files!&lt;/li&gt;
&lt;li&gt;conf/ → Configuration files (server.xml, tomcat-users.xml).&lt;/li&gt;
&lt;li&gt;logs/ → Log files (look for catalina.out).&lt;/li&gt;
&lt;li&gt;bin/ → Startup/shutdown scripts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Deploying Your JRuby WAR File 🚀
&lt;/h3&gt;

&lt;p&gt;This is the whole reason we're here—the simplest deployment process you'll find:&lt;/p&gt;

&lt;p&gt;Build your JRuby application into a WAR file (e.g., using Warbler).&lt;/p&gt;

&lt;p&gt;Copy the WAR file to the webapps directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp myapp.war /var/lib/tomcat9/webapps/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Tomcat to trigger the auto-extraction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart tomcat9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tomcat will automatically extract your myapp.war into a folder called &lt;code&gt;/var/lib/tomcat9/webapps/myapp/&lt;/code&gt;. Your JRuby application is then instantly available:&lt;/p&gt;

&lt;p&gt;➡️ Access your application at: &lt;a href="http://localhost:8080/myapp/" rel="noopener noreferrer"&gt;http://localhost:8080/myapp/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  💻 Optional: Using the Manager UI for Deployment
&lt;/h3&gt;

&lt;p&gt;While the file copy method is fast, Tomcat also provides an easy web interface, the Manager Console, which is great for seeing the status of your deployed apps.&lt;/p&gt;

&lt;p&gt;Important: By default, no login is configured, so you need to set one up manually.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set Up the Manager User
You need to define a user with the manager-gui role in the configuration file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/tomcat9/tomcat-users.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following role and user definitions right before the closing  tag. Remember to change the password!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;role rolename="manager-gui"/&amp;gt;
&amp;lt;role rolename="manager-script"/&amp;gt;
&amp;lt;user username="admin" password="mypassword!" roles="manager-gui,manager-script"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart and Log In
Restart Tomcat to load the new user configuration:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo systemctl restart tomcat9&lt;/code&gt;&lt;br&gt;
Now, navigate to the console:&lt;/p&gt;

&lt;p&gt;➡️ Open: &lt;a href="http://localhost:8080/manager" rel="noopener noreferrer"&gt;http://localhost:8080/manager&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the credentials you just set up (admin/mypassword!) to log in. From here, you can deploy new WAR files directly through the UI without manually touching the file system.&lt;br&gt;
in. From here, you can deploy new WAR files directly through the UI without manually touching the file system.&lt;/p&gt;

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

&lt;p&gt;When is Tomcat the right tool?&lt;/p&gt;

&lt;p&gt;✅ Quick WAR testing (my use case for the JRuby PR).&lt;br&gt;
✅ Lightweight web apps where you only need Servlets/JSP.&lt;br&gt;
❌ NOT when you need the full Java EE stack (transactions, enterprise security, messaging queues, etc.).&lt;/p&gt;

&lt;p&gt;For developers working with JRuby, using a lightweight server like Tomcat dramatically cuts down the time between code changes and seeing results. &lt;br&gt;
In my case, my prototype is a Rails application on JRuby but without Database, specially built for carry on the discussion. &lt;/p&gt;

&lt;p&gt;I am not sure whether setting up oracle DB connection within Tomcat will work or not, if you have any idea, please share your thoughts, I will try a full-fledged Rails app with Oracle in Tomcat in coming days.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>war</category>
      <category>tomcat</category>
      <category>weblogic</category>
    </item>
    <item>
      <title>Amazon Q developer cheatsheet learnt</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Thu, 04 Sep 2025 12:30:44 +0000</pubDate>
      <link>https://dev.to/santattech/amazon-q-developer-cheatsheet-learnt-16l</link>
      <guid>https://dev.to/santattech/amazon-q-developer-cheatsheet-learnt-16l</guid>
      <description>&lt;p&gt;&lt;strong&gt;Amazon Q Developer&lt;/strong&gt; is a generative UI-powered tool for project development. Based on my use, I try to prepare some quick notes for future use. I am using Q cli versioned 1.14.1. &lt;/p&gt;

&lt;p&gt;It is not entirely free, you will have some free credits every month, you can get the price details here &lt;a href="https://aws.amazon.com/q/developer/pricing/?p=qdev&amp;amp;z=subnav&amp;amp;loc=7" rel="noopener noreferrer"&gt;https://aws.amazon.com/q/developer/pricing/?p=qdev&amp;amp;z=subnav&amp;amp;loc=7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From our experience, this tool helped us complete 4 days’ worth of work in just 1 day. That’s the level of productivity boost it can bring!&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Big picture in simple form
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ff79lxdxxgitj7hlvv35q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ff79lxdxxgitj7hlvv35q.png" alt=" " width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Few commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;q help
q settings
q whoami
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Learn the Core Workflows&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As a professional, you’ll use Q mostly for &lt;strong&gt;code assistance + AWS workflows&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core commands you need to know:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;q generate&lt;/code&gt; → generate or refactor code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;q explain&lt;/code&gt; → explain existing code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;q test&lt;/code&gt; → write or improve unit tests&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;q run&lt;/code&gt; → execute code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;q fix&lt;/code&gt; → debug/resolve errors&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;q ask&lt;/code&gt; → general-purpose Q&amp;amp;A (like ChatGPT but AWS/dev focused)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  You can check the usage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/usage&lt;/code&gt; =&amp;gt; Shows a summary of your current usage of Q.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/compact&lt;/code&gt; =&amp;gt; Compacts the session history by summarizing previous prompts + responses. Keeps the conversation lighter and prevents Q from hitting context/token limits.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/quit&lt;/code&gt; =&amp;gt; Ends the current Q session in your terminal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/clear&lt;/code&gt; =&amp;gt; Clears the current conversation history with Q&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/save&lt;/code&gt; =&amp;gt; Saves the current conversation to a file for later use.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;q chat --resume&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 ==&amp;gt; It will start from where you finished.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;explain app/models/user.rb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;generate rspec tests for app/models/mev.rb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ask "list all s3 buckets in my account"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test app/models/user.rb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fix "DB connection error in database.yml file"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ask "where in this project do we send emails?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Go deeper
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; Always run Q inside your project root so it reads your code. &lt;/li&gt;
&lt;li&gt; Be specific → “generate a Rails service object for sending user notification email” &amp;gt; “generate email code.”&lt;/li&gt;
&lt;li&gt; refine to refine the answer given by q, if you do not believe q in first instance&lt;/li&gt;
&lt;li&gt;Security mindset: Do not copy blindly&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  AWS Pro Workflows
&lt;/h4&gt;

&lt;p&gt;Q to speed up AWS development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infra as Code (Pulumi/CDK/Terraform)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;q chat --resume&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;| &lt;code&gt;ask "command to list all ec2 instances in ap-southeast-1"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;will give the bash command for using with aws-cli&lt;/p&gt;

&lt;p&gt;| &lt;code&gt;generate pulumi code in yaml for listing all ec2 instances in ap-southeast-1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Will create the &lt;code&gt;Pulumi.dv.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now &lt;code&gt;pulumi up&lt;/code&gt; will help to list down the instances&lt;/p&gt;

&lt;p&gt;NB: When you give prompt, explain more to get more accurate result, q will behave like a senior developer&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;generate s3 upload code&lt;/code&gt;&lt;br&gt;
vs&lt;/p&gt;

&lt;p&gt;&lt;code&gt;generate rails service object UploadFileService with method call(file:, bucket:) using aws-sdk-s3 gem, include unit tests with rspec&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Project Intelligence?
&lt;/h3&gt;

&lt;p&gt;It is from Promptz.dev. It transforms Amazon Q Developer from a stateless assistant into a persistent development partner. That means it remembers and understands your project over time, not just for a session.&lt;/p&gt;

&lt;p&gt;You need to add the rules in the markdown file. &lt;br&gt;
&lt;code&gt;.amazonq/rules/*&lt;/code&gt;;&lt;br&gt;
Once you add the rules, you can type: &lt;code&gt;Initialize Project Intelligence&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It will automatically create some markdown files and maintain this small set of Markdown files that help Amazon Q understand and remember your project.&lt;/p&gt;

&lt;p&gt;You will get the list of markdown files and their use here in detail: &lt;a href="https://www.promptz.dev/rules/rule/project-intelligence-dbd52e23" rel="noopener noreferrer"&gt;https://www.promptz.dev/rules/rule/project-intelligence-dbd52e23&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>aws</category>
      <category>ai</category>
    </item>
    <item>
      <title>🚀 FastAPI vs Rails — Notes from a Rails Developer Learning FastAPI</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Sat, 23 Aug 2025 17:16:58 +0000</pubDate>
      <link>https://dev.to/santattech/fastapi-vs-rails-notes-from-a-rails-developer-learning-fastapi-336o</link>
      <guid>https://dev.to/santattech/fastapi-vs-rails-notes-from-a-rails-developer-learning-fastapi-336o</guid>
      <description>&lt;p&gt;I recently explored FastAPI alongside my usual Rails work and built a small project to learn the essentials:&lt;/p&gt;

&lt;p&gt;✅ CRUD APIs (with items)&lt;br&gt;
✅ User authentication with JWT (login &amp;amp; registration)&lt;br&gt;
✅ Integrated a Weather API wrapper&lt;br&gt;
✅ DB operation, I use sqlite3&lt;br&gt;
✅ Hands-on with Alembic migrations &amp;amp; SQLModel&lt;br&gt;
✅ Password hashing&lt;br&gt;
✅ Handling Environment variables&lt;br&gt;
and a few more things...&lt;/p&gt;

&lt;p&gt;The learning curve was smooth, and I like how FastAPI makes API development clean. 🚀&lt;/p&gt;

&lt;p&gt;Here’s the repo if you’d like to take a look 👇&lt;br&gt;
🔗 [&lt;a href="https://github.com/qisantanu/fastapi_learn" rel="noopener noreferrer"&gt;https://github.com/qisantanu/fastapi_learn&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Would love feedback and ideas on what to add next!&lt;/p&gt;

&lt;h4&gt;
  
  
  To help myself memorize and compare, I drafted this write-up. Hopefully, it helps anyone else coming from Rails into FastAPI.
&lt;/h4&gt;

&lt;p&gt;🔑 Key Comparisons&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzc4353b0mbn62c35xx1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzc4353b0mbn62c35xx1r.png" alt=" " width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am planning to explore for Background jobs anf file upload. I’ll keep updating this as I learn more. If you’re also coming from Rails, maybe this cheat sheet will help!&lt;/p&gt;

&lt;p&gt;See my code in the above shared gihub link. &lt;br&gt;
Thanks!!!&lt;/p&gt;

</description>
      <category>python</category>
      <category>rails</category>
      <category>ruby</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>Global interpreter lock</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Mon, 14 Jul 2025 10:08:49 +0000</pubDate>
      <link>https://dev.to/santattech/global-interpreter-lock-27l8</link>
      <guid>https://dev.to/santattech/global-interpreter-lock-27l8</guid>
      <description>&lt;h2&gt;
  
  
  What is GIL in Ruby?
&lt;/h2&gt;

&lt;p&gt;GIL stands for Global Interpreter Lock. It's a mutex (mutual exclusion) used by Ruby’s interpreter — specifically MRI (Matz’s Ruby Interpreter), the default Ruby implementation — to ensure only one thread executes Ruby code at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 Why does GIL exist?
&lt;/h2&gt;

&lt;p&gt;Ruby (MRI) is written in C. The GIL is used to:&lt;/p&gt;

&lt;p&gt;Simplify memory management in MRI’s C-based interpreter.&lt;/p&gt;

&lt;p&gt;Avoid race conditions in the Ruby interpreter internals (especially garbage collection).&lt;/p&gt;

&lt;h2&gt;
  
  
  🧵 How does it affect threads?
&lt;/h2&gt;

&lt;p&gt;Even if you write multi-threaded Ruby code, only one thread executes at a time (in terms of Ruby code execution). The threads take turns, not run in true parallel — this is known as cooperative concurrency.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;threads = 10.times.map do
  Thread.new do
    1_000_000.times { |i| i * i }
  end
end

threads.each(&amp;amp;:join)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though there are 10 threads, due to GIL, only one will run Ruby code at any given time (on a single core). &lt;strong&gt;Only one thread will execute Ruby code at a time, regardless of how many CPU cores your machine has.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧵 But threads are still useful when...
&lt;/h3&gt;

&lt;p&gt;Even though only one thread runs Ruby code at a time, I/O operations release the GIL, so:&lt;/p&gt;

&lt;p&gt;✅ Multi-threading works well for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;HTTP/network requests (e.g., Net::HTTP, open-uri)&lt;/li&gt;
&lt;li&gt;File I/O&lt;/li&gt;
&lt;li&gt;Database queries&lt;/li&gt;
&lt;li&gt;Sleeping/waiting
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'net/http'
require 'uri'

urls = [
  'https://santattech.com',
  'https://google.com',
  'https://qi.com'
]

threads = urls.map do |url|
  Thread.new do
    response = Net::HTTP.get(URI(url))
    puts "#{url} - #{response.bytesize} bytes"
  end
end

threads.each(&amp;amp;:join)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, each thread will process an I/O HTTP request. So, GIL will be released.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ What is parallel then?
&lt;/h2&gt;

&lt;p&gt;Ruby threads can still benefit from parallelism when:&lt;/p&gt;

&lt;p&gt;They are waiting on I/O (e.g., file reads, network).&lt;/p&gt;

&lt;p&gt;They are running native extensions or C code that release the GIL (e.g., some database drivers, image processing libraries).&lt;/p&gt;

&lt;p&gt;So, GIL doesn't block concurrency, but it limits parallelism in CPU-bound Ruby code.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Alternatives to bypass GIL:
&lt;/h2&gt;

&lt;p&gt;Use processes instead of threads&lt;br&gt;
Use &lt;code&gt;Process.fork&lt;/code&gt; or tools like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;parallel gem&lt;/li&gt;
&lt;li&gt;sidekiq (for background jobs)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Parallel gem internally uses &lt;code&gt;Process.fork&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;require 'parallel'

results = Parallel.map([1, 2, 3, 4, 5], in_processes: 3) do |i|
  puts "PID #{Process.pid} is processing #{i}"
  sleep 1
  i * i
end

puts "Results: #{results.inspect}"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NB: &lt;strong&gt;I think parallel gem is available inside Rails by default from Rails 7.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Use JRuby
&lt;/h2&gt;

&lt;p&gt;These alternative Ruby implementations don’t have GIL, so they support true parallel threading on multicore CPUs.  It uses the JVM (Java Virtual Machine), allowing true multi-threading.&lt;/p&gt;

&lt;h4&gt;
  
  
  RUBY
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fyivamb9wc0n3vdt0r40f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fyivamb9wc0n3vdt0r40f.png" alt=" " width="480" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  JRUBY
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F86kucy88psztkxwjdpgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F86kucy88psztkxwjdpgw.png" alt=" " width="595" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;GIL is not a problem when the application is doing HTTP requests, I/O operations or the file operations. Also, GIL makes the Ruby code execution simpler &amp;amp; safer, though multi-threading is not allowed. If you need multi-threading can opt for JRuby.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Choosing the correct index in Oracle</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Tue, 27 May 2025 08:13:34 +0000</pubDate>
      <link>https://dev.to/santattech/choosing-the-correct-index-in-oracle-4m6g</link>
      <guid>https://dev.to/santattech/choosing-the-correct-index-in-oracle-4m6g</guid>
      <description>&lt;h3&gt;
  
  
  How to choose the correct index
&lt;/h3&gt;

&lt;p&gt;I have an index in an Oracle table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX "I_TBL_XYZ_COLA"
      ON "TBL_XYZ" ("COLA") LOCAL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the query is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT  
sum(COLB) from tbl_xyz partition (TBL_XYZ_3) 
where MAP_ID='XXXXX' COLA &amp;gt;= to_date('2023/04/21 17:00:00', 'YYYY/MM/DD HH24:MI:SS') 
AND COLA &amp;lt; to_date('2025/05/21 20:00:00', 'YYYY/MM/DD HH24:MI:SS');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is scanning about 4 million of data.&lt;/p&gt;

&lt;p&gt;It is not using the index, instead, it is doing the scan, taking &lt;strong&gt;9 secs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's try to use the index forcefully in Oracle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT /*+ INDEX(TBL_XYZ I_TBL_XYZ_COLA) */
  COLB, COLA
FROM TBL_XYZ PARTITION (TBL_XYZ_4)
WHERE COLA &amp;gt;= TO_DATE('2025/05/22 10:00:00', 'YYYY/MM/DD HH24:MI:SS')
  AND COLA &amp;lt; TO_DATE('2025/05/23 00:00:00', 'YYYY/MM/DD HH24:MI:SS');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ❌ When Forcing Index Hurts
&lt;/h3&gt;

&lt;p&gt;I observed: Forcing index = &lt;strong&gt;57s&lt;/strong&gt;, vs full scan = &lt;strong&gt;9s&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I explained the query, which is using the index. But still it is taking this much time. So, Oracle knows the index and purposefully avoids it.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠  Why Oracle Chooses Full Scan
&lt;/h3&gt;

&lt;p&gt;Oracle's optimizer is not ignoring the index — it's making a cost-based decision:&lt;/p&gt;

&lt;p&gt;Our query is aggregating (SUM) over a large range.&lt;/p&gt;

&lt;p&gt;The index would require:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scanning many index blocks. It is supposed to use the index for doing this. &lt;/li&gt;
&lt;li&gt;But, then visiting table blocks to get COLB (since COLB is not in the index)&lt;/li&gt;
&lt;li&gt;A full scan reads the partition sequentially and can do aggregation efficiently.&lt;/li&gt;
&lt;li&gt;In this case, full scan is actually faster.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ✅ So What Can we Do?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  ✅ Option 1: Create a Covering Index (Best when query is frequent)
&lt;/h4&gt;

&lt;p&gt;If this query (or similar) is run often on this partition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX I_TBL_XYZ_NEW_INDEX
ON TBL_XYZ (COLB, COLA)
LOCAL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows Oracle to:&lt;/p&gt;

&lt;p&gt;Do index-only range scan&lt;/p&gt;

&lt;p&gt;Get both COLA and COLB from the index&lt;/p&gt;

&lt;p&gt;Do the SUM without table access&lt;/p&gt;

&lt;p&gt;✅ Now I can avoid the &lt;strong&gt;57s&lt;/strong&gt; table lookup penalty.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✅ Option 2: Use Materialized View or Precomputed Stats
&lt;/h4&gt;

&lt;p&gt;If you always run SUM over long ranges:&lt;/p&gt;

&lt;p&gt;Consider precomputing aggregates by hour/day and storing them&lt;/p&gt;

&lt;p&gt;Use a materialized view to keep the results updated. I  will not go into those details.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✅ Option 3: Parallelism
&lt;/h4&gt;

&lt;p&gt;For huge partitions, enable parallel query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER SESSION ENABLE PARALLEL QUERY;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT /*+ parallel(tbl_xyz, 4) */
  SUM(COLB)
FROM tbl_xyz PARTITION (tbl_xyz_3)
WHERE COLA BETWEEN ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have gone with &lt;strong&gt;Option 1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But the result is not impressive. It is still doing the full scan, and the new index is not even used.&lt;/p&gt;

&lt;p&gt;The reason is our index is for &lt;code&gt;COLB + COLA&lt;/code&gt; combination. In Oracle indexing it actually matters. &lt;br&gt;
&lt;code&gt;COLB + COLA != COLA + COLB&lt;/code&gt; in this case.&lt;/p&gt;

&lt;p&gt;Since in the query, it is looking up with &lt;strong&gt;COLA&lt;/strong&gt;, if the index leading column is that, it would be helpful for Oracle.&lt;/p&gt;

&lt;p&gt;So I dropped the index and created a new index&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX I_TBL_XYZ_NEW_INDEX
ON TBL_XYZ (COLA, COLB)
LOCAL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this time, I ran the query, &lt;strong&gt;9 secs got reduced to 1.5 secs&lt;/strong&gt;. I explained the query. And this time it is straightforward, no more scanning, but it is using the index only for looking up the data it wants to sum.  &lt;/p&gt;

&lt;p&gt;So yes — in this case, the full scan is better unless you cover the query with a better index.&lt;/p&gt;

&lt;p&gt;And our query is also now more robust since&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is not doing full scanning of table.&lt;/li&gt;
&lt;li&gt;It is using the table partition to reduce the load.&lt;/li&gt;
&lt;li&gt;Covering index helps to avoid the partition scan &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Summary&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full scan is faster   Accept Oracle's plan (9s is efficient for large partitions)&lt;/li&gt;
&lt;li&gt;Forced index is slower    Avoid forcing — it causes expensive table access&lt;/li&gt;
&lt;li&gt;Want speedup  Use covering index on (COLA, COLB)&lt;/li&gt;
&lt;li&gt;Need instant results  Use materialized view or precomputed aggregates&lt;/li&gt;
&lt;li&gt;High volume partition Enable parallelism for faster aggregation&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>🚀 Rails + Tailwind not refreshing CSS ?</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Fri, 11 Apr 2025 10:40:26 +0000</pubDate>
      <link>https://dev.to/santattech/rails-tailwind-not-refreshing-css--59ia</link>
      <guid>https://dev.to/santattech/rails-tailwind-not-refreshing-css--59ia</guid>
      <description>&lt;p&gt;In Rails 8, many developers run into an annoying issue: Tailwind CSS changes don’t reflect while coding. In this post, I’ll walk you through what went wrong and how I fixed it in my project.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 How Tailwind is Integrated in Rails
&lt;/h2&gt;

&lt;p&gt;There are couple of libraries of Ruby which helps you to include it in your project easily if your projects are Rails 7+.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rails 7 comes by default with &lt;code&gt;tailwindcss-rails&lt;/code&gt;. It does not use Node.js and instead compiles Tailwind via Ruby using tailwindcss-rails, which wraps the Tailwind CLI.&lt;/li&gt;
&lt;li&gt;On the other hand, Rails 8 does not use &lt;code&gt;tailwindcss-rails&lt;/code&gt;, by default, it comes with &lt;code&gt;cssbundling-rails&lt;/code&gt;. But under the hood, this now uses Node.js + PostCSS via cssbundling-rails, not the tailwindcss-rails gem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s more flexible and modern.&lt;/p&gt;

&lt;h3&gt;
  
  
  🕵️ What we will debug
&lt;/h3&gt;

&lt;p&gt;Our tech stack is a Rails 8 project, but we are not using &lt;code&gt;cssbundling-rails&lt;/code&gt;. The project has the codebase which migrated from Rails 7. So, &lt;code&gt;cssbundling-rails&lt;/code&gt; are not part of this. We have the &lt;code&gt;tailwindcss-rails&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS not refreshing? Things to check
&lt;/h3&gt;

&lt;h4&gt;
  
  
  ✅ Tailwind build watcher running?
&lt;/h4&gt;

&lt;p&gt;Many of us are running &lt;code&gt;rails server&lt;/code&gt;(old school) or &lt;code&gt;rails s&lt;/code&gt;&lt;br&gt;
But if you use the mentioned library, it uses the Tailwind CLI under the hood. Run this to start the watcher:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bin/dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The content of dev executable&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Frovn695qw1ahguhbidc5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Frovn695qw1ahguhbidc5.png" alt=" " width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see, it is silently installing &lt;code&gt;foreman&lt;/code&gt; in your system. &lt;code&gt;foreman&lt;/code&gt; is a manager for Procfile based applications. It expects a Procfile.dev&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkq7of5jx88zg29x8f503.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkq7of5jx88zg29x8f503.png" alt=" " width="798" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This tells you different commands you want to run simultaneously from a single terminal. &lt;/p&gt;

&lt;p&gt;So when you start a &lt;code&gt;bin/dev&lt;/code&gt;, something will look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbo1ar44k4t1h5pf490is.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbo1ar44k4t1h5pf490is.png" alt=" " width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Tip: If you don't have bin/dev, generate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec rails generate tailwindcss:install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check if Tailwind stylesheet is loaded in the layout
&lt;/h3&gt;

&lt;p&gt;Ensure your layout includes the correct stylesheet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Do not forget to Restart the Rails server and clear cache
&lt;/h3&gt;

&lt;p&gt;Sometimes changes don’t take effect due to caching. Try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/dev # or restart Puma/Webrick
rails tmp:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also run &lt;code&gt;rails assets:clobber&lt;/code&gt; to be in safer side.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 tailwind.css - is it included in your layout ?
&lt;/h3&gt;

&lt;p&gt;Check if the file is getting generated and modified when you update your CSS. By default, Tailwind builds output to &lt;code&gt;app/assets/builds/tailwind.css&lt;/code&gt;. If that file isn't being updated when you change your Tailwind styles, the CLI might not be running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Another issue found, we are using SCSS
&lt;/h3&gt;

&lt;p&gt;✅ Tailwind’s watcher only watches .css files, not .scss&lt;br&gt;
When you're using Tailwind CLI (e.g., via tailwindcss-rails or cssbundling-rails), it does not process or watch SCSS files like .scss or .sass.&lt;/p&gt;

&lt;p&gt;Tailwind CLI only understands plain CSS with these special directives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn’t know how to compile SCSS → CSS. &lt;/p&gt;

&lt;p&gt;Tailwind also recommends using CSS variables and stick with Tailwind-only solution.&lt;br&gt;
But if you really need SCSS, we have to process this file to convert to CSS so that tailwind can understand. We need some tool like Saas (Syntactically Awesome Stylesheet).&lt;/p&gt;

&lt;p&gt;We have the C/C++ implementation of this SaaS compiler.&lt;br&gt;
There is a ruby library &lt;code&gt;sassc-rails&lt;/code&gt; to rescue us.&lt;/p&gt;

&lt;p&gt;so our manifest will be simpler under &lt;code&gt;app/assets/stylesheets/application.scss&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;/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self
 */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will have the file &lt;code&gt;app/assets/stylesheets/application.tailwind.css&lt;/code&gt;, which contains&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the SCSS files we can keep under the &lt;code&gt;app/assets/stylesheets&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At last, please check the configuration file under &lt;code&gt;config/tailwind.config.js&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;const defaultTheme = require('tailwindcss/defaultTheme')

module.exports = {
  content: [
    './public/*.html',
    './app/helpers/**/*.rb',
    './app/javascript/**/*.js',
    './app/views/**/*.{erb,haml,html,slim}',
    './app/assets/stylesheets/**/*.{css,scss}'
  ],
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter var', ...defaultTheme.fontFamily.sans],
      },
    },
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/aspect-ratio'),
    require('@tailwindcss/typography'),
    require('@tailwindcss/container-queries'),
  ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the testing time, start your application by &lt;code&gt;bin/dev&lt;/code&gt;, puma got activated, Tailwind cli got activated.&lt;/p&gt;

&lt;p&gt;Update a CSS file, reload the browser, and hopefully the update will be shown in the browser. 💥&lt;/p&gt;

&lt;h3&gt;
  
  
  🔆 Conclusion
&lt;/h3&gt;

&lt;p&gt;Rails + Tailwind is now a days a trendy combo. Before using you need to know which integration method you’re using (&lt;code&gt;tailwindcss-rails&lt;/code&gt; vs &lt;code&gt;cssbundling-rails&lt;/code&gt;). If you’re using the Tailwind CLI via Ruby, just make sure the watcher is running, your styles are properly linked, and SCSS is being compiled correctly.&lt;br&gt;
Happy coding!!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>tailwindcss</category>
      <category>programming</category>
      <category>web</category>
    </item>
    <item>
      <title>Cropping image on canvas</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Mon, 10 Mar 2025 05:18:41 +0000</pubDate>
      <link>https://dev.to/santattech/cropping-image-on-canvas-1m1p</link>
      <guid>https://dev.to/santattech/cropping-image-on-canvas-1m1p</guid>
      <description>&lt;p&gt;Cropping an image nowadays is a widespread requirement for the website. Many libraries in Javascript will help us to do this with many options like Jcrop and cropper are a few renowned libraries. &lt;/p&gt;

&lt;p&gt;However, this library will help you select the portion of the image either in rectangular or square shape &lt;code&gt;(aspect ratio=&amp;gt; 1:1)&lt;/code&gt;, depending on the aspect ratio you want to provide. It will also provide you with some locations like &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; coordinates. Eventually, we can extract the image from the original one. Here, extracting means we will redraw the image.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML Canvas
&lt;/h3&gt;

&lt;p&gt;Canvas is like a white art paper where we can draw image. To draw an image there is one function named &lt;code&gt;drawImage()&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Create a canvas using HTML
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F87xx15hoa1pn1nv9jf9e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F87xx15hoa1pn1nv9jf9e.png" alt=" " width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Create a drawing environment
&lt;/h4&gt;

&lt;p&gt;When you call &lt;code&gt;canvas.getContext('2d')&lt;/code&gt;, you're obtaining a 2D rendering context object that provides methods and properties for drawing and manipulating content on the canvas. This context is essentially your toolbox for creating graphics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2w4dw2rzwcrxpzud4jwy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2w4dw2rzwcrxpzud4jwy.png" alt=" " width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So basically, it is creating an environment, where many drawing options will be enabled.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Create an Image object
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fab63j4isqidtsxjbnw4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fab63j4isqidtsxjbnw4o.png" alt=" " width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4: Now use drawImage()
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;img.onload = function() {
    // Basic drawImage: draw the entire image at (10, 10)
    ctx.drawImage(img, 10, 10);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have a canvas, of 300 * 300, below the original image&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fcddaspeksel0vk6afbm3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fcddaspeksel0vk6afbm3.png" alt=" " width="327" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, it will start from the top left, and then 10 by 10.&lt;/p&gt;

&lt;p&gt;Another option&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ctx.drawImage(img, 30, 20, 200, 150);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F8zcr2wf3hr2ydrn0utjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8zcr2wf3hr2ydrn0utjb.png" alt=" " width="320" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another most complex option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ctx.drawImage(img, 50, 50, 200, 100, 
      0, 0, 200, 100
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9rms1uzrfwoto995quza.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9rms1uzrfwoto995quza.png" alt=" " width="313" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will take the output image from the original image's (50,50) location at a scale of (200, 100). And the second line mentions, in the canvas. it will put the taken image from the beginning (0,0) location at a scale of (200, 100)&lt;/p&gt;

&lt;h3&gt;
  
  
  Let us try another example
&lt;/h3&gt;

&lt;p&gt;Let us put the calculated image in the exact location from the location, it got cropped.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ctx.drawImage(img, 50, 50, 200, 100, 
      50, 50, 200, 100
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fk3tzirsq86ujf7ixtnr6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fk3tzirsq86ujf7ixtnr6.png" alt=" " width="319" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this above example, I think we will get a clearer picture.&lt;/p&gt;

&lt;p&gt;One point to take note is that the original image is rendered with 300*300 as the height and width.&lt;/p&gt;

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

&lt;p&gt;The &lt;code&gt;drawImage&lt;/code&gt; method is designed to render specific parts of an image rather than remove them. Since it operates on pixel coordinates, accurately determining these coordinates is crucial for precise cropping. However, manually finding these values can be error-prone. This is where JavaScript cropping libraries, such as Jcrop and Cropper.js, prove invaluable by simplifying the process and ensuring accurate results.&lt;/p&gt;

&lt;p&gt;Let me know if you'd like any further refinements! 🚀&lt;/p&gt;

</description>
      <category>drawimage</category>
      <category>html</category>
      <category>web</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How do we migrate to local indexing in Oracle</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Sun, 02 Mar 2025 17:26:42 +0000</pubDate>
      <link>https://dev.to/santattech/how-do-we-migrate-to-local-indexing-in-oracle-3j9f</link>
      <guid>https://dev.to/santattech/how-do-we-migrate-to-local-indexing-in-oracle-3j9f</guid>
      <description>&lt;p&gt;We are dealing with an Oracle table that can have 2k million records. The table is partitioned. It is a high ingest table. &lt;br&gt;
We have the required indexing to find the data. The problem arises when we are truncating partitions and creating data as per requirement. The queries were becoming slower even when there was indexing.&lt;/p&gt;
&lt;h4&gt;
  
  
  Checking the status:
&lt;/h4&gt;

&lt;p&gt;In Oracle, you can check the status of the index which will tell you whether the indexing is valid or not, which means it is usable or not. There is a way to check the status by writing SQL query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select INDEX_NAME, STATUS, TABLE_OWNER, TABLE_NAME, UNIQUENESS 
from USER_INDEXES WHERE table_name = 'TABLE_NAME'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F1ebggccnykskhm2nt8nk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F1ebggccnykskhm2nt8nk.png" alt=" " width="284" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The status column says valid, which means it is usable. 😆&lt;/p&gt;

&lt;p&gt;We discovered, the status as unusable. So there is always chance that truncation of a partition can trigger a need to rebuild the index. &lt;/p&gt;

&lt;p&gt;Rebuilding an index can be a costly operation, depending on the size of the index, and the complexity of the index. It can take more CPU, memory, and disk space, also sometimes it needs additional disk space as temporary spaces are involved for operations. Also sometimes, it is time-consuming.&lt;/p&gt;

&lt;p&gt;But if the index is unusable, obviously we need to rebuild the index, I think there is no other alternative.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Local Index in Oracle?
&lt;/h3&gt;

&lt;p&gt;In this case, we have decided to move to the local index from the global index. When working with large datasets in Oracle, partitioning tables can significantly improve query performance and manageability.&lt;br&gt;
A local index is an index that is automatically partitioned in alignment with the table partitions. &lt;strong&gt;Unlike a global index, which spans all partitions&lt;/strong&gt;, a local index contains separate index partitions corresponding to each table partition.&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Characteristics:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Each partition of a table has its corresponding index partition.&lt;/li&gt;
&lt;li&gt;If a table partition is dropped or truncated, its corresponding local index partition is also removed or truncated.&lt;/li&gt;
&lt;li&gt;Queries that target specific partitions can use the corresponding local index, improving performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnnz331crfofuhnp3n0l7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnnz331crfofuhnp3n0l7.png" alt=" " width="790" height="428"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Creating a local index
&lt;/h4&gt;

&lt;p&gt;Our table is partitioned as I mentioned before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX INDEX_NAME ON TABLE_NAME(COLUMN_NAME) LOCAL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LOCAL&lt;/code&gt; ensures that the index is partitioned in the same way as the table.&lt;/li&gt;
&lt;li&gt;The index will automatically have partitions p1, p2, and p3 matching the table’s partitions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, you can use specific table space. &lt;code&gt;TABLESPACE SPACE_NAME&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  When to Use Local Indexes?
&lt;/h4&gt;

&lt;p&gt;Local indexes are beneficial in scenarios such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Partition maintenance: Dropping or truncating a partition does not affect other partitions’ indexes, unlike global indexes.&lt;/li&gt;
&lt;li&gt;Partition pruning: Queries targeting specific partitions can efficiently use local indexes.&lt;/li&gt;
&lt;li&gt;Efficient parallel processing: Local indexes allow parallel queries to work on specific partitions independently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Checking the status:
&lt;/h4&gt;

&lt;p&gt;For local indexing also you can check the status. If you execute the query I mentioned it will give you some out with the index names. Let me show you:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmdr6s1r9bnkd0kbvkccj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmdr6s1r9bnkd0kbvkccj.png" alt="Output of status" width="318" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here it is showing as N/A,😮 😮 😮 sometimes developers get confused that the local index became unusable. But that is not the case. N/A means this does not apply to the local index. For the global index, the status should be coming as &lt;code&gt;VALID/ INVALID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The correct way to do this is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select partition_name, status from user_ind_partitions 
where index_name='INDEX_NAME'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgu79axkztvgs1txez4xm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgu79axkztvgs1txez4xm.png" alt=" " width="162" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So it shows the status of each of the partitions, and it clearly shows it is usable 😍 😍, in most cases, the local index does not get corrupted even if we are doing truncation of partitions frequently. Which is part of the partition maintenance. &lt;/p&gt;

&lt;h4&gt;
  
  
  Rebuild local index
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER INDEX INDEX_NAME REBUILD PARTITION p1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OR&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE TABLE_NAME
   MODIFY PARTITION p1 REBUILD UNUSABLE LOCAL INDEXES;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since there are multiple indexes on a partition, initially the dev team was looking for the unusable index by querying, that is why I like the second one as you don't have to search for the unusable indexes.&lt;/p&gt;

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

&lt;p&gt;Local indexes are an essential tool when working with partitioned tables in Oracle. They improve performance, simplify maintenance, and enable better query optimization. &lt;br&gt;
&lt;em&gt;If I missed anything&lt;/em&gt;, let me know in the comments. &lt;/p&gt;

</description>
      <category>oracle</category>
      <category>database</category>
      <category>aws</category>
      <category>programming</category>
    </item>
    <item>
      <title>Firefighting with bashrc: How I restore my Ubuntu terminal</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Sun, 02 Mar 2025 04:07:14 +0000</pubDate>
      <link>https://dev.to/santattech/firefighting-with-bashrc-how-i-restore-my-ubuntu-terminal-5958</link>
      <guid>https://dev.to/santattech/firefighting-with-bashrc-how-i-restore-my-ubuntu-terminal-5958</guid>
      <description>&lt;h2&gt;
  
  
  Restoring My Ubuntu Terminal After a Corrupt &lt;code&gt;.bashrc&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Recently, I encountered an issue with my .bashrc file on my Ubuntu system that left my terminal unusable, eventually all stuffs like developing, running, testing halts. Here’s how I identified and resolved the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issue Begins
&lt;/h2&gt;

&lt;p&gt;I was trying to install WebLogic on my local system to check for compatibility issues. My Java version at the time was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openjdk version "1.8.0_302"
OpenJDK Runtime Environment (build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM (build 25.302-b08, mixed mode)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I attempted to execute the WebLogic installer JAR file with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java -jar fmw-....jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it fails.&lt;/p&gt;

&lt;p&gt;Checking the error logs, I found the following message:&lt;br&gt;
&lt;strong&gt;the openjdk jvm is not supported on this platform.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Switching to Oracle Java
&lt;/h3&gt;

&lt;p&gt;The installer required Oracle Java, but I was using SDKMAN! to manage my Java versions. SDKMAN is similar to RVM for Ruby, but due to licensing restrictions, it no longer provides Oracle Java.&lt;/p&gt;

&lt;p&gt;To work around this, I decided to switch to Zulu JDK but ultimately opted to manually install Oracle JDK 8 instead.&lt;/p&gt;

&lt;p&gt;Steps I Took:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Downloaded Oracle JDK 8 and extracted it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Placed it in /opt/java/jdk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set JAVA_HOME, ensuring it pointed to the new JDK instead of SDKMAN.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After setting the new path, I verified the Java version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java version "1.8.0_431"
Java(TM) SE Runtime Environment (build 1.8.0_431-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.431-b10, mixed mode)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;😆&lt;/p&gt;

&lt;p&gt;💚 Now, Java was correctly set up.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Persistent PATH Issue
&lt;/h2&gt;

&lt;p&gt;Later, I navigated to the installer’s directory in a &lt;strong&gt;new terminal window&lt;/strong&gt; and re-ran the command—only to face the same error. Checking the Java version revealed that my shell was still using &lt;strong&gt;OpenJDK&lt;/strong&gt; instead of the newly installed Oracle JDK.&lt;/p&gt;

&lt;p&gt;At this point, I realized that my &lt;strong&gt;PATH was not updated permanently&lt;/strong&gt;. Since &lt;code&gt;.bashrc&lt;/code&gt; is responsible for configuring interactive non-login shells, I needed to reload it.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;source ~/.bashrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Problem Begins
&lt;/h3&gt;

&lt;p&gt;The command &lt;strong&gt;froze&lt;/strong&gt;. Nothing happened. Even pressing &lt;strong&gt;Ctrl + C&lt;/strong&gt; didn’t work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I opened a new terminal—same issue, it was stuck.&lt;/li&gt;
&lt;li&gt;I restarted my system multiple times—no improvement.&lt;/li&gt;
&lt;li&gt;The terminal simply hung, &lt;strong&gt;waiting indefinitely&lt;/strong&gt;. 😨&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Troubleshooting &lt;code&gt;.bashrc&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Realizing that &lt;code&gt;.bashrc&lt;/code&gt; was likely causing the issue, I manually edited the file:&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;undid all my recent changes&lt;/strong&gt;—but the problem persisted. As a last resort, I &lt;strong&gt;deleted all content&lt;/strong&gt; inside &lt;code&gt;.bashrc&lt;/code&gt;, and my terminal started working again. 🚀&lt;/p&gt;

&lt;p&gt;Unfortunately, this also meant I lost all my Java, Ruby environment configurations. 😞. And all my projects starts throwing error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the Culprit
&lt;/h3&gt;

&lt;p&gt;I carefully restored my &lt;code&gt;.bashrc&lt;/code&gt; content &lt;strong&gt;line by line&lt;/strong&gt; to identify which one was causing the issue. Eventually, I found the problematic line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source &amp;lt;(ng completion script)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This stale Angular CLI autocomplete command was preventing the script from executing correctly, causing the terminal to hang.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Final Fix&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I removed the problematic line, then ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the terminal worked smoothly! 🎉&lt;/p&gt;

&lt;p&gt;I re-ran the WebLogic installer, and this time, the installation window popped up successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Lessons Learned&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Be cautious when modifying&lt;/strong&gt; &lt;code&gt;.bashrc&lt;/code&gt; A single incorrect command can render your terminal unusable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If your terminal hangs after updating&lt;/strong&gt; &lt;code&gt;.bashrc&lt;/code&gt; try restoring an earlier version by editing or clearing the file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use&lt;/strong&gt; &lt;code&gt;source ~/.bashrc&lt;/code&gt; &lt;strong&gt;carefully.&lt;/strong&gt; Ensure the file is free from syntax errors before sourcing it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check your PATH persistence.&lt;/strong&gt; If Java (or any tool) isn’t behaving as expected, verify that the correct PATH is applied across all terminal sessions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; Keep a backup of your &lt;code&gt;.bashrc&lt;/code&gt; file before making major changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp ~/.bashrc ~/.bashrc.bak
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, you can always restore a working version if things go wrong!&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>linux</category>
      <category>programming</category>
      <category>bash</category>
    </item>
    <item>
      <title>Progressive web app styling</title>
      <dc:creator>Santanu Bhattacharya</dc:creator>
      <pubDate>Sat, 01 Mar 2025 05:16:55 +0000</pubDate>
      <link>https://dev.to/santattech/progressive-web-app-styling-52ho</link>
      <guid>https://dev.to/santattech/progressive-web-app-styling-52ho</guid>
      <description>&lt;p&gt;Recently I have worked on adding styles for a progressive web application. It is a Ruby on Rails application. Here are some key learnings I noted down:&lt;/p&gt;

&lt;h3&gt;
  
  
  To make your button look and feel more like a mobile app button, you can enhance it with the following adjustments:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Add a subtle shadow:&lt;/strong&gt; This gives the button a slightly raised appearance, making it look tappable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adjust padding:&lt;/strong&gt; Make the button larger and more finger-friendly for touch screens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rounded corners:&lt;/strong&gt; Increase the border radius to make it more modern and appealing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ripple or press effect:&lt;/strong&gt; Simulate a tactile response when the user taps on it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Color contrast:&lt;/strong&gt; Make the colors pop and ensure they adhere to accessibility standards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Focus state:&lt;/strong&gt; Provide visual feedback for accessibility of the button.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Focus effect:&lt;/strong&gt; Add visual feedback when the input is focused.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finger friendly design:&lt;/strong&gt; Ensure input fields are finger-friendly for better usability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Placeholder styling:&lt;/strong&gt; Ensure placeholder text with some styling which will not draw much attention&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's an example of a well-styled button for mobile-friendly applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn {
  background-color: #fbf9f4;
  border: 1px solid #897b51;
  border-radius: 1rem; /* Increased for a more modern look */
  cursor: pointer;
  color: #897b51;
  padding: 0.75rem 2rem; /* Larger padding for touch-friendly size */
  text-transform: uppercase;
  transition: all 0.3s ease;
  font-size: 1rem; /* Slightly larger font for readability */
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* Subtle shadow for raised effect */

  &amp;amp;:hover {
    background-color: #d3b88a;
    color: #fff;
    box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15); /* Enhance shadow on hover */
  }

  &amp;amp;:active {
    transform: scale(0.97); /* Slight press effect */
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Reduced shadow on press */
  }

  &amp;amp;:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(205, 151, 0, 0.4); /* Focus ring for accessibility */
  }

  &amp;amp;.primary {
    background-color: #cd9700;
    color: #f4f0e8;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);

    .icon {
      fill: #f4f0e8;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Notes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Padding and font-size:&lt;/strong&gt; Make sure the button size adheres to the Apple and Google Material design guidelines for touch targets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive feedback:&lt;/strong&gt; You can implement ripple effects for a material design feel. This we can do using Javascript OR CSS as well. While I haven't implemented this yet, it could add a nice touch in some scenarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test on devices:&lt;/strong&gt; Always test the button on different mobile devices to ensure usability and consistency.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>pwa</category>
      <category>rails</category>
      <category>css</category>
    </item>
  </channel>
</rss>
