Setup 🛠 Rails 8 App – Part 10: PostgreSQL Into The Action

For a Ruby on Rails 8 application, the choice of database depends on your specific needs, but here’s a breakdown of the best options and when to use each:

PostgreSQL (Highly Recommended)

Best overall choice for most Rails apps.

Why:

  • First-class support in Rails.
  • Advanced features like full-text search, JSONB support, CTEs, window functions.
  • Strong consistency and reliability.
  • Scales well vertically and horizontally (with tools like Citus).
  • Used by: GitHub, Discourse, Basecamp, Shopify.

Use if:

  • You’re building a standard Rails web app or API.
  • You need advanced query features or are handling complex data types (e.g., JSON).

SQLite (For development/testing only)

  • Lightweight, file-based.
  • Fast and easy to set up.
  • But not recommended for production.

Use if:

  • You’re building a quick prototype or local dev/testing app.
  • NOT for multi-user production environments.

MySQL / MariaDB

  • Also supported by Rails.
  • Can work fine for simpler applications.
  • Lacks some advanced features (like robust JSON support or full Postgres-style indexing).
  • Not the default in many modern Rails setups.

Use if:

  • Your team already has MySQL infrastructure or legacy systems.
  • You need horizontal scaling with Galera Cluster or similar setups.

Others (NoSQL like MongoDB, Redis, etc.)

  • Use Redis for caching and background job data (not as primary DB).
  • Use MongoDB or other NoSQL only if your data model really demands it (e.g., unstructured documents, event sourcing).

Recommendation Summary:

Use CaseRecommended DB
Production web/API appPostgreSQL
Dev/prototyping/local testingSQLite
Legacy systems/MySQL infrastructureMySQL/MariaDB
Background jobs/cachingRedis
Special needs (e.g., documents)MongoDB (with caution)

If you’re starting fresh or building something scalable and modern with Rails 8, go with PostgreSQL.

Let’s break that down:

💬 What does “robust JSON support” mean?

PostgreSQL supports a special column type: json and jsonb, which lets you store structured JSON data directly in your database — like hashes or objects.

Why it matters:

  • You can store dynamic data without needing to change your schema.
  • You can query inside the JSON using SQL (->, ->>, @>, etc.).
  • You can index parts of the JSON — for speed.

🔧 Example:

You have a products table with a specs column that holds tech specs in JSON:

specs = {
  "color": "black",
  "brand": "Libas",
  "dimensions": {"chest": "34", "waist": "30", "shoulder": "13.5"}
}

You can query like:

SELECT * FROM products WHERE specs->>'color' = 'black';

Or check if the JSON contains a value:

SELECT * FROM products WHERE specs @> '{"brand": "Libas"}';

You can even index specs->>'color' to make these queries fast.


💬 What does “full Postgres-style indexing” mean?

PostgreSQL supports a wide variety of powerful indexing options, which improve query performance and flexibility.

⚙️ Types of Indexes PostgreSQL supports:

Index TypeUse Case
B-TreeDefault; used for most equality and range searches
GIN (Generalized Inverted Index)Fast indexing for JSON, arrays, full-text search
Partial IndexesIndex only part of the data (e.g., WHERE active = true)
Expression IndexesIndex a function or expression (e.g., LOWER(email))
Covering Indexes (INCLUDE)Fetch data directly from the index, avoiding table reads
  • B-Tree Indexes: B-tree indexes are more suitable for single-value columns.
  • When to Use GIN Indexes: When you frequently search for specific elements within arrays, JSON documents, or other composite data types.
  • Example for GIN Indexes: Imagine you have a table with a JSONB column containing document metadata. A GIN index on this column would allow you to quickly find all documents that have a specific author or belong to a particular category. 

Why does this matter for our shopping app?

  • We can store and filter products with dynamic specs (e.g., kurtas, shorts, pants) without new columns.
  • Full-text search on product names/descriptions.
  • Fast filters: color = 'red' AND brand = 'Libas' even if those are stored in JSON.
  • Index custom expressions like LOWER(email) for case-insensitive login.

💬 What are Common Table Expressions (CTEs)?

CTEs are temporary result sets you can reference within a SQL query — like defining a mini subquery that makes complex SQL easier to read and write.

WITH recent_orders AS (
  SELECT * FROM orders WHERE created_at > NOW() - INTERVAL '7 days'
)
SELECT * FROM recent_orders WHERE total > 100;

  • Breaking complex queries into readable parts.
  • Re-using result sets without repeating subqueries.
In Rails (via with from gems like scenic or with_cte):
Order
  .with(recent_orders: Order.where('created_at > ?', 7.days.ago))
  .from('recent_orders')
  .where('total > ?', 100)

💬 What are Window Functions?

Window functions perform calculations across rows related to the current row — unlike aggregate functions, they don’t group results into one row.

🔧 Example: Rank users by their score within each team:
SELECT
  user_id,
  team_id,
  score,
  RANK() OVER (PARTITION BY team_id ORDER BY score DESC) AS rank
FROM users;
Use cases:
  • Ranking rows (like leaderboards).
  • Running totals or moving averages.
  • Calculating differences between rows (e.g. “How much did this order increase from the last?”).
🛤 In Rails:

Window functions are available through raw SQL or Arel. Here’s a basic example:

User
  .select("user_id, team_id, score, RANK() OVER (PARTITION BY team_id ORDER BY score DESC) AS rank")

CTEs and Window functions are fully supported in PostgreSQL, making it the go-to DB for any Rails 8 app that needs advanced querying.

JSONB Support

JSONB stands for “JSON Binary” and is a binary representation of JSON data that allows for efficient storage and retrieval of complex data structures.

This can be useful when you have data that doesn’t fit neatly into traditional relational database tables, such as nested or variable-length data structures.

Absolutely — storing JSON in a relational database (like PostgreSQL) can be super powerful when used wisely. It gives you schema flexibility without abandoning the structure and power of SQL. Here are real-world use cases for using JSON columns in relational databases:

Here are real-world use cases for using JSON columns in relational databases:

🔧 1. Flexible Metadata / Extra Attributes

Let users store arbitrary attributes that don’t require schema changes every time.

Use case: Product variants, custom fields

t.jsonb :metadata

{
  "color": "red",
  "size": "XL",
  "material": "cotton"
}

=> Good when:

  • You can’t predict all the attributes users will need.
  • You don’t want to create dozens of nullable columns.

🎛️ 2. Storing Settings or Preferences

User or app settings that vary a lot.

Use case: Notification preferences, UI layout, feature toggles

{
  "email": true,
  "sms": false,
  "theme": "dark"
}

=> Easy to store and retrieve as a blob without complex joins.

🌐 3. API Response Caching

Store external API responses for caching or auditing.

Use case: Storing Stripe, GitHub, or weather API responses.

t.jsonb :api_response

=> Avoids having to map every response field into a column.

📦 4. Storing Logs or Events

Use case: Audit trails, system logs, user events

{
  "action": "login",
  "timestamp": "2025-04-18T10:15:00Z",
  "ip": "123.45.67.89"
}

=> Great for capturing varied data over time without a rigid schema.

📊 6. Embedded Mini-Structures

Use case: A form builder app storing user-created forms and fields.

{
  "fields": [
    { "type": "text", "label": "Name", "required": true },
    { "type": "email", "label": "Email", "required": false }
  ]
}

=> When each row can have nested, structured data — almost like a mini-document.

🕹️ 7. Device or Browser Info (User Agents)

Use case: Analytics, device fingerprinting

{
  "browser": "Safari",
  "os": "macOS",
  "version": "17.3"
}

=> You don’t need to normalize or query this often — perfect for JSON.


JSON vs JSONB in PostgreSQL

Use jsonb over json unless you need to preserve order or whitespace.

  • jsonb is binary format → faster and indexable
  • You can do fancy stuff like:
SELECT * FROM users WHERE preferences ->> 'theme' = 'dark';

Or in Rails:

User.where("preferences ->> 'theme' = ?", 'dark')

store and store_accessor

They let you treat JSON or text-based hash columns like structured data, so you can access fields as if they were real database columns.

🔹 store

  • Used to declare a serialized store (usually a jsonb, json, or text column) on your model.
  • Works best with key/value stores.

👉 Example:

Let’s say your users table has a settings column of type jsonb:

# migration
add_column :users, :settings, :jsonb, default: {}

Now in your model:

class User < ApplicationRecord
  store :settings, accessors: [:theme, :notifications], coder: JSON
end

You can now do this:

user.theme = "dark"
user.notifications = true
user.save

user.settings
# => { "theme" => "dark", "notifications" => true }

🔹 store_accessor

A lightweight version that only declares attribute accessors for keys inside a JSON column. Doesn’t include serialization logic — so you usually use it with a json/jsonb/text column that already works as a Hash.

👉 Example:

class User < ApplicationRecord
  store_accessor :settings, :theme, :notifications
end

This gives you:

  • user.theme, user.theme=
  • user.notifications, user.notifications=
🤔 When to Use Each?
FeatureWhen to Use
storeWhen you need both serialization and accessors
store_accessorWhen your column is already serialized (jsonb, etc.)

If you’re using PostgreSQL with jsonb columns — it’s more common to just use store_accessor.

Querying JSON Fields
User.where("settings ->> 'theme' = ?", "dark")

Or if you’re using store_accessor:

User.where(theme: "dark")

💡 But remember: you’ll only be able to query these fields efficiently if you’re using jsonb + proper indexes.


🔥 Conclusion:

  • PostgreSQL can store, search, and index inside JSON fields natively.
  • This lets you keep your schema flexible and your queries fast.
  • Combined with its advanced indexing, it’s ideal for a modern e-commerce app with dynamic product attributes, filtering, and searching.

To install and set up PostgreSQL on macOS, you have a few options. The most common and cleanest method is using Homebrew. Here’s a step-by-step guide:

Setup 🛠 Rails 8 App – Part 7: Mastering Debugbar 👾 for Rails Performance Optimization

As Rails developers, we’ve all been there – your application starts slowing down as data grows, pages take longer to load, and memory usage spikes. Before you blame Rails itself or consider rewriting your entire application, you should profile your app to understand what’s really happening behind the scenes.

Most of the time, the issue lies in how the app is written: unnecessary SQL queries, excessive object allocations, or inefficient code patterns. Before you think about rewriting your app or switching frameworks, profile it.

That’s where Rails Debugbar shines— It helps you identify bottlenecks like slow database queries, excessive object allocations, and memory leaks – all from a convenient toolbar at the bottom of your development environment.


🤔 What is Rails Debugbar?

Rails Debugbar is a browser-integrated dev tool that adds a neat, powerful panel at the bottom of your app in development. It helps you answer questions like:

  • How long is a request taking?
  • How many SQL queries are being executed?
  • How many Ruby objects are being allocated?
  • Which parts of my code are slow?

It’s like a surgeon’s X-ray for your app—giving you visibility into internals without needing to dig into logs or guess. Get a better understanding of your application performance and behavior (SQL queries, jobs, cache, routes, logs, etc)


⚙️ Installation & Setup (Rails 8)

Prerequisites

  • Ruby on Rails 5.2+ (works perfectly with Rails 8)
  • A Ruby version supported by your Rails version

1. Add it to your Gemfile:

group :development do
  gem 'debugbar'
end

Then run:

bundle install

2. Add the Debugbar layout helpers in your application layout:

In app/views/layouts/application.html.erb, just before the closing </head> and </body> tags:

<%= debugbar_head if defined?(Debugbar) %>
...
<%= debugbar_body if defined?(Debugbar) %>

That’s it! When you restart your server, you’ll see a sleek Debugbar docked at the bottom of the screen.

You can see ActionCable interacting with debugbar_channel in logs:

[ActionCable] Broadcasting to debugbar_channel: [{id: "xxxx-xxxx-xxxx-xxxx", meta: {controller: "ProductsController", action: "show", params: {"controller" => "products", "action" => "show", "id" => "3"}, format: :html, method: "GET", path: "/products/3", status: 200, view_runtime: 10.606000004219823, db_runtime: 0.44599999819...

23:47:17 web.1  | Debugbar::DebugbarChannel transmitting [{"id" => "xxxx-xxxx-xxxx-xxxx", "meta" => {"controller" => "ProductsController", "action" => "show", "params" => {"controller" => "products", "action" => "show", "id" => "3"}, "format" => "html", "method" => "GET", "path" => "/products/3", "status" => 200, "view_runtime" => 10.6... (via streamed from debugbar_channel)

23:47:17 web.1  | Debugbar::DebugbarChannel#receive({"ids" => ["xxxx-xxxx-xxxx-xxxx"]})
23:47:17 web.1  | [ActionCable] Broadcasting to debugbar_channel: []

23:47:17 web.1  | Debugbar::DebugbarChannel transmitting [] (via streamed from debugbar_channel)

📚 Official links for reference:


🔍 Exploring the Debugbar Tabs

Rails Debugbar includes several tabs. Let’s go through the most useful ones—with real-world examples of how to interpret and improve performance using the data.

1. Queries Tab

This tab shows all SQL queries executed during the request, including their duration in milliseconds.

Example:

You see this in the Queries tab:

SELECT * FROM users WHERE email = 'test@example.com'  (15ms)
SELECT * FROM products WHERE user_id = 1                 (20ms)
SELECT * FROM comments WHERE product_id IN (...)         (150ms)

You realize:

  • The third query is taking 10x more time.
  • You’re not using eager loading, and it’s triggering N+1 queries.

How to Fix:

Update your controller:

@products = Product.includes(:comments).where(user_id: 1)

This loads the comments in a single query, reducing load time and object allocation.


2. Timeline Tab

Gives you a timeline breakdown of how long each part of the request takes—view rendering, database, middleware, etc.

Example:

You notice that rendering a partial takes 120ms, way more than expected.

<%= render 'shared/sidebar' %>

How to Fix:

Check the partial for:

  • Heavy loops or database calls
  • Uncached helper methods

Move the partial to use a fragment cache:

<% cache('sidebar') do %>
  <%= render 'shared/sidebar' %>
<% end %>

Another Example Problem:
If you notice view rendering takes 800ms for a simple page.

Solution:
Investigate partials being rendered. You might be:

  • Rendering unnecessary partials
  • Using complex helpers in views
  • Need to implement caching
# Before
<%= render @products %> # Renders _product.html.erb for each

# After (with caching)
<% @products.each do |product| %>
  <% cache product do %>
    <%= render product %>
  <% end %>
<% end %>

3. Memory Tab

Tracks memory usage and object allocations per request.

Example:

You load a dashboard page and see 25,000+ objects allocated. Yikes.

Dig into the view and see:

<% User.all.each do |user| %>
  ...
<% end %>

That’s loading all users into memory.

How to Fix:

Use pagination or lazy loading:

@users = User.page(params[:page]).per(20)

Now the object count drops dramatically.


4. Environment & Request Info

See request parameters, environment variables, session data, and headers.

Example:

You’re debugging an API endpoint and want to confirm the incoming headers or params—Debugbar shows them neatly in this tab.

It can help identify:

  • Wrong content-type headers
  • CSRF issues
  • Auth headers or missing cookies

💡 Debugbar Best Practices

  • Use it early: Don’t wait until your app is slow—profile as you build.
  • Watch out for hidden N+1 in associations, partials, or background jobs.
  • Keep an eye on object counts to reduce memory pressure in production.
  • Use fragment and Russian doll caching where needed, based on render timelines.
  • Regularly review slow pages with Debugbar open—it’s a development-time lifesaver.

💭 Final Thoughts

Rails Debugbar offers an easy, visual way to profile and optimize your Rails 8 app. Whether you’re debugging a slow page, inspecting a query storm, or chasing down memory leaks, this tool gives you insight without friction.

So before you overhaul your architecture or blame Rails, fire up Debugbar—and fix the real issues.

to be modified..  🚀

Setting Up ⚙️ SSH in your system

SSH (Secure Shell) is used to establish secure remote connections over an unsecured network, enabling secure access, management, and data transfer on remote systems, including running commands, transferring files, and managing applications.

Setup SSH keys:

To create an SSH key and add it to your GitHub account, follow these steps:

1. Generate an SSH Key

ssh-keygen -t ed25519 -C "your-email@example.com"
  • Replace "your-email@example.com" with your GitHub email.
  • If prompted, press Enter to save the key in the default location (~/.ssh/id_ed25519).
  • Set a passphrase (optional for security).

2. Start the SSH Agent

eval "$(ssh-agent -s)"

3. Add the SSH Key to the Agent

ssh-add ~/.ssh/id_ed25519

4. Copy the SSH Key to Clipboard

cat ~/.ssh/id_ed25519.pub | pbcopy   # macOS
cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard   # Linux
clip < ~/.ssh/id_ed25519.pub   # Windows (Git Bash)

(If xclip is not installed, use sudo apt install xclip on Linux)


5. Add the SSH Key to GitHub

  • Go to GitHub → Settings → SSH and GPG keys (GitHub SSH Keys).
  • Click New SSH Key.
  • Paste the copied key into the field and give it a title.
  • Click Add SSH Key.

6. Test the SSH Connection

ssh -T git@github.com

You should see a message like:

Hi username! You've successfully authenticated, but GitHub does not provide shell access.

Now you can clone, push, and pull repositories without entering your GitHub password!

You may be wondering what is ed25519 ?

ed25519 is a modern cryptographic algorithm used for generating SSH keys. It is an alternative to the older RSA algorithm and is considered more secure and faster.

Why Use ed25519 Instead of RSA?

  1. Stronger Securityed25519 provides 128-bit security, while RSA requires a 4096-bit key for similar security.
  2. Smaller Key Size – The generated keys are much shorter than RSA keys, making them faster to use.
  3. Faster Performanceed25519 is optimized for speed, especially on modern hardware.
  4. Resistant to Certain Attacks – Unlike RSA, ed25519 is resistant to side-channel attacks.

Why GitHub Recommends ed25519?

  • Since 2021, GitHub suggests using ed25519 over RSA because of better security and efficiency.
  • Older RSA keys (e.g., 1024-bit) are now considered weak.

When Should You Use ed25519?

  • Always, unless you’re working with old systems that do not support it.
  • If you need maximum security, speed, and smaller key sizes.

Example: Creating an ed25519 SSH Key

ssh-keygen -t ed25519 -C "your-email@example.com"

This creates a strong and secure SSH key for GitHub authentication.

What is the SSH Agent?

The SSH agent is a background process that securely stores your SSH private keys and manages authentication.

Instead of entering your private key passphrase every time you use SSH (e.g., for git push), the agent remembers your key after you add it.


Why Do We Need the SSH Agent?

  1. Avoid Entering Your Passphrase Repeatedly
  • If your SSH key has a passphrase, you would normally need to enter it every time you use git push or ssh.
  • The agent caches the key in memory so you don’t need to enter the passphrase every time.
  1. Automatic Authentication
  • Once the agent has your key, it can sign SSH requests for authentication automatically.
  1. Keeps Your Private Key Secure
  • Your private key stays in memory and is not exposed on disk after adding it.

What Do These Commands Do?

1️⃣ Start the SSH Agent

eval "$(ssh-agent -s)"
  • This starts the SSH agent in the background.
  • The eval "$(ssh-agent -s)" command initializes the agent and prints its process ID (PID), confirming it’s running.

2️⃣ Add the SSH Key to the Agent

ssh-add ~/.ssh/id_ed25519
  • This adds your private key (~/.ssh/id_ed25519) to the agent.
  • Now, the agent will remember the key and use it when making SSH connections.

How to Check If Your Key is Added?

Run:

ssh-add -l

This lists all keys currently added to the agent. If your key is listed, it means the agent is working correctly.


Example: How This Helps?

Without the agent:

git push origin main
# Every time, you need to enter your SSH passphrase

With the agent:

ssh-add ~/.ssh/id_ed25519
git push origin main
# No need to enter your passphrase again!

Conclusion
  • The SSH agent stores your private key securely in memory.
  • It automates authentication, so you don’t need to enter your passphrase for every SSH request.
  • Adding the key with ssh-add lets Git and SSH use it without prompting.

Now, you can git push and git pull seamlessly!

But the question is: Can this make unauthorized persons to access with this commands without ssh passphrase?


Does using ssh-agent make your system less secure? Let’s break it down.

Can Someone Else Use My SSH Key Without a Passphrase?

✅ No, If Your System is Secure

  • The SSH agent only runs under your user session.
  • Other users on the same machine cannot access your agent.
  • Your private key is never written to disk in an unprotected way.
  • The agent only allows authentication, not direct access to your key.

⚠️ Yes, If Someone Gets Access to Your Session

  • If an attacker gains access to your system (e.g., via malware, or if you leave your computer unlocked), they might use your active SSH agent to authenticate without needing your passphrase.
  • However, they cannot extract your private key from the agent.

How to Improve Security?

If you want extra security, here are a few things you can do:

1️⃣ Remove Keys from Agent When Not Needed

After using your SSH key, you can remove it from the agent:

ssh-add -D

This removes all stored keys. Next time you push, you’ll need to re-enter your passphrase.


2️⃣ Use -t (Timeout) for Auto Removal

To automatically remove the key after a set time:

ssh-add -t 3600 ~/.ssh/id_ed25519  # Removes the key after 1 hour


3️⃣ Lock Your Screen When Away

If someone gets access to your logged-in session, they could use your agent to authenticate without needing the passphrase.

Always lock your screen (Ctrl + L or Win + L on Windows/Linux, Cmd + Ctrl + Q on Mac) when stepping away.


4️⃣ Disable Agent Forwarding (Extra Security)

By default, SSH agent forwarding (ssh -A) can expose your keys to remote servers. If you don’t need it, disable it by editing:

nano ~/.ssh/config

And adding:

Host *
    ForwardAgent no

Summary
  1. The SSH agent only runs in your session, so no one else can access it unless they get control of your user session.
  2. Attackers cannot steal your private key from the agent, but if they have access to your session, they could use it.
  3. To be safe, remove keys when not needed (ssh-add -D), use timeouts (-t), and always lock your computer.

You’re now both secure and productive with SSH! 🚀

Setup 🛠 Rails 8 App – Part 3: Git setup, modify gitignore, git config

So now let’s push the code to github repository. Before that there is some final checks need to be done from our end.

Check .gitignore file and update

✅ Files/Folders to Include in .gitignore

Here’s a breakdown of which files/folders should be added to .gitignore in your Rails project:

These files are user-specific or environment-specific and should not be committed to Git.

1️⃣ .dockerignore → ❌ Ignore from .gitignore

  • Keep this file if you’re using Docker.
  • It’s like .gitignore but for Docker, helping to reduce Docker image size.
  • Do not add it to .gitignore if you need it.

2️⃣ .github/ → ✅ Add to .gitignore (If personal CI/CD configs)

  • If this contains GitHub Actions or issue templates, keep it in the repo.
  • If it’s just for personal workflows, add it to .gitignore.

3️⃣ .kamal/ → ✅ Add to .gitignore

  • This contains deployment secrets and configuration files for Kamal (deployment tool).
  • It’s usually auto-generated and should not be committed.

4️⃣ .vscode/ → ✅ Add to .gitignore

  • User-specific VSCode settings, should not be committed.
  • Different developers use different editors.

Keep These Files in Git (Don’t Add to .gitignore)

These files are important for project configuration.

1️⃣ .gitattributes → ❌ Keep in Git

  • Defines how Git handles line endings and binary files.
  • Helps avoid conflicts on Windows/Linux/Mac.

2️⃣ .gitignore → ❌ Keep in Git

  • Defines ignored files, obviously should not be ignored itself.

3️⃣ .rubocop.yml → ❌ Keep in Git

  • This is for Rubocop linting rules, which helps maintain coding style.
  • All developers should follow the same rules.

4️⃣ .ruby-version → ❌ Keep in Git

  • Defines the Ruby version for the project.
  • Ensures all team members use the same Ruby version.

Final .gitignore Entries Based on Your Files

# Ignore log files, temp files, and dependencies
/log/
/tmp/
.bundle/
/node_modules/

# Manually added
# Ignore editor & environment-specific configs
.vscode/

# Ignore deployment configs
.kamal/

# Ignore personal GitHub configs (if applicable)
.github/

Final Summary

FolderInclude in Git?Why?
log/❌ IgnoreDynamically generated logs
public/✅ Keep (except public/assets/)Static files like favicon, error pages
script/✅ KeepOld Rails script files (if used)
storage/❌ IgnoreActiveStorage uploads (except seed/)
test/✅ KeepContains important test cases
tmp/❌ IgnoreTemporary runtime files
vendor/❌ Ignore (except custom libraries)Third-party libraries

First time git setup

# You can view all of your settings and where they are coming from using

git config --list --show-origin

# Your Identity: The first thing you should do is to set your user name and email address.

git config --global user.name "Abhilash"
git config --global user.email abhilash@example.com

# configure the default text editor that will be used when Git needs you to type in a message

git config --global core.editor emacs
git config --global core.editor "code --wait"     # vs code
git config --global -e      # verify editor

# command to list all the settings Git can find at that point

git config --list
git config user.name

Add your ssh key to your github. Check the post: https://railsdrop.com/2025/03/30/setting-up-ssh-in-your-system/

Initial commit: Execute the Git commands

Run the following commands in your rails app folder:

git add .
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:abhilashak/design_studio.git
git remote -v     # check the remote endpoints
git push -u origin main

git log      # check commit details

What It Does:

git branch -M main
  1. Renames the current branch to main.
  2. The -M flag forcefully renames the branch (overwrites if needed).

Common Use Case:

  • If your branch is named master and you want to rename it to main (which is now the default in many repositories).
  • If you created a branch with a different name and want to standardise it as main.

Example Usage:

git branch -M main
git push -u origin main

This renames the current branch to main and then pushes it to the remote repository.

Use github ssh option: it checks the ssh key that you setup in your github account for that machine.
http option asks your github credentials to login.

The -u option in the command:

git push -u origin main

What Does -u Do?

The -u flag stands for --set-upstream. It sets the upstream branch for main, which means:

  • It links your local branch (main) to the remote branch (main on origin).
  • After running this command once, you can simply use:
  git push

instead of git push origin main, because Git now knows where to push.

Example Use Case:

If you just created a new branch (main in this case) and are pushing it for the first time:

git push -u origin main

This ensures that main always pushes to origin/main without needing to specify it every time.

After Running This Command:

✅ Next time, you can simply use:

git push
git pull

without needing to specify origin main again.

For better git work flow

Check the post: https://railsdrop.com/2025/03/29/git-workflow-best-practices-for-your-development-process/

Want to See Your Upstream Branch?

Run:

git branch -vv

This shows which remote branch your local branches are tracking.

to be continued.. 🚀


Setup 🛠 Rails 8 App – Part 1: Setup All Necessary Configurations | Ruby | Rails setup | Kamal | Rails Generations

Ruby on Rails 8 introduces several improvements that make development easier, more secure, and more maintainable. In this guide, we’ll walk through setting up a new Rails 8 application while noting the significant configurations and features that come out of the box.

1. Check Your Ruby and Rails Versions

If not installed Ruby 3.4 and Rails 8.0 please check: https://railsdrop.com/2025/02/11/installing-and-setup-ruby-3-rails-8-vscode-ide-on-macos-in-2025/

Before starting, ensure that you have the correct versions of Ruby and Rails installed:

$ ruby -v
ruby 3.4.1

$ rails -v
Rails 8.0.1

If you don’t have these versions installed, update them using your package manager or version manager (like rbenv or RVM).

2. Create a New Rails 8 Application

Run the following command to create a new Rails app:

$ rails new design_studio

Noteworthy Files and Directories Created

Here are some interesting files and directories that are generated with a new Rails 8 app:

 create  .ruby-version
 create  bin/brakeman
 create  bin/rubocop
 create  bin/docker-entrypoint
 create  .rubocop.yml
 create  .github/workflows
 create  .github/workflows/ci.yml
 create  config/cable.yml
 create  config/storage.yml
 create  config/initializers/content_security_policy.rb
 create  config/initializers/filter_parameter_logging.rb
 create  config/initializers/new_framework_defaults_8_0.rb

Key Takeaways:

  • Security & Code Quality Tools: Brakeman (security scanner) and RuboCop (code style linter) are included by default.
  • Docker Support: The presence of bin/docker-entrypoint suggests better built-in support for containerized deployment.
  • GitHub Actions Workflow: The .github/workflows/ci.yml file provides default CI configurations.
  • Enhanced Security: The content_security_policy.rb initializer helps enforce a strict security policy.
  • New Rails Defaults: The new_framework_defaults_8_0.rb initializer helps manage breaking changes in Rails 8.

Rails automatically creates the following during the creation of the rails new app.

a. Configuring Import Maps and Installing Turbo & Stimulus

Rails 8 still defaults to Import Maps for JavaScript package management, avoiding the need for Node.js and Webpack:

$ rails turbo:install stimulus:install

This creates the following files:

create    config/importmap.rb
create    app/javascript/controllers
create    app/javascript/controllers/index.js
create    app/javascript/controllers/hello_controller.js
append    config/importmap.rb

Key Takeaways:

  • Import Maps: Defined in config/importmap.rb, allowing dependency management without npm.
  • Hotwired Support: Turbo and Stimulus are automatically configured for modern front-end development.
  • Generated Controllers: Stimulus controllers are pre-configured inside app/javascript/controllers/.

b. Deploying with Kamal

Kamal simplifies deployment with Docker and Kubernetes. Rails 8 includes built-in support:

$ bundle binstubs kamal
$ bundle exec kamal init

This results in:

Created .kamal/secrets file
Created sample hooks in .kamal/hooks

Key Takeaways:

  • Automated Deployment Setup: Kamal provides easy-to-use deployment scripts.
  • Secret Management: The .kamal/secrets file ensures secure handling of credentials.
  • Deployment Hooks: Custom hooks allow pre- and post-deployment scripts for automation.

c. Setting Up Caching and Queues with Solid Cache, Queue, and Cable

NOTE: Rails automatically creates this for you while creating the rails app.

Rails 8 includes Solid Cache, Solid Queue, and Solid Cable for enhanced performance and scalability:

$ rails solid_cache:install solid_queue:install solid_cable:install

This creates:

create  config/cache.yml
create  db/cache_schema.rb
create  config/queue.yml

Key Takeaways:

  • Caching Support: config/cache.yml manages application-wide caching.
  • Database-Powered Queue System: Solid Queue simplifies background job management without requiring external dependencies like Sidekiq.
  • Real-Time WebSockets: Solid Cable offers Action Cable improvements for real-time features.

3. Rails 8 Migration Enhancements

Rails 8 provides new shortcuts and syntax improvements for database migrations:

NOT NULL Constraints with ! Shortcut

You can impose NOT NULL constraints directly from the command line using !:

# Example for not null constraints: 
➜ rails generate model User name:string!

Type Modifiers in Migrations

Rails 8 allows passing commonly used type modifiers directly via the command line. These modifiers are enclosed in curly braces {} after the field type.

# Example for model generation: 
➜ rails generate model Product name:string description:text
# Example for passing modifiers: 
➜ rails generate migration AddDetailsToProducts 'price:decimal{5,2}' supplier:references{polymorphic}

Generating a Scaffold for the Product Model

Let’s generate a complete scaffold for our Product model:

✗ rails generate scaffold product title:string! description:text category:string color:string 'size:string{10}' 'mrp:decimal{7,2}' 'discount:decimal{7,2}' 'rating:decimal{1,1}'
➜  design_studio git:(main) ✗ rails -v
Rails 8.0.1
➜  design_studio git:(main) ✗ ruby -v
ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [arm64-darwin24]
➜  design_studio git:(main) ✗ rails generate scaffold product title:string! description:text category:string color:string 'size:string{10}' 'mrp:decimal{7,2}' 'discount:decimal{7,2}' 'rating:decimal{1,1}'

Using the Rails Resource Generator

The rails g resource command is a powerful way to generate models, controllers, migrations, and routes all in one go. This is particularly useful when setting up RESTful resources in a Rails application.

Basic Syntax

➜ rails g resource product

This command creates the necessary files for a new resource, including:

  • A model (app/models/product.rb)
  • A migration file (db/migrate/)
  • A controller (app/controllers/product_controller.rb)
  • Routes in config/routes.rb
  • A test file (test/controllers/product_controller_test.rb or spec/)

Example Usage

To generate a Post resource with attributes:

➜ rails g resource Product title:string! description:text brand:references

This will:

  1. Create a Product model with title and description attributes.
  2. Add a brand_id foreign key as a reference.
  3. Apply a NOT NULL constraint on title (! shortcut).
  4. Generate a corresponding migration file.
  5. Set up routes automatically (resources :products).

Running the Migration

After generating a resource, apply the migration to update the database:

➜ rails db:migrate


Difference Between resource and scaffold

Rails provides both rails g resource and rails g scaffold, but they serve different purposes:

Featurerails g resourcerails g scaffold
Generates a Model
Generates a Migration
Generates a Controller✅ (empty actions)✅ (full CRUD actions)
Generates Views (HTML/ERB)✅ (index, show, new, edit, etc.)
Generates Routes
Generates Helper Files
Generates Tests
  • rails g resource is minimal—it generates only essential files without view templates. It’s useful when you want more control over how your views and controller actions are built.
  • rails g scaffold is more opinionated and generates full CRUD functionality with prebuilt forms and views, making it ideal for rapid prototyping.

If you need full CRUD functionality quickly, use scaffold. If you prefer a leaner setup with manual control over implementation, use resource.

Conclusion

Rails 8 significantly enhances the development experience with built-in security tools, CI/CD workflows, streamlined deployment via Kamal, and modern front-end support with Turbo & Stimulus. It also improves caching, background jobs, and real-time features with Solid tools.

These improvements make Rails 8 a robust framework for modern web applications, reducing the need for additional dependencies while keeping development efficient and secure.

Enjoy Rails! 🚀

Setting Up Terminal 🖥️ for Development on MacOS (Updated 2025)

If you’re setting up your MacBook for development, having a well-configured terminal is essential. This guide will walk you through installing and configuring a powerful terminal setup using Homebrew, iTerm2, and Oh My Zsh, along with useful plugins.

1. Install Homebrew

Homebrew is a package manager that simplifies installing software on macOS.

Open the Terminal and run:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

After installation, add Homebrew to your PATH by running the following commands:

echo >> ~/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

Verify installation:

brew --version

Check here.

2. Install iTerm2

The default macOS Terminal is functional but lacks advanced features. iTerm2 is a powerful alternative.

Install it using Homebrew:

brew install --cask iterm2

Open iTerm2 from your Applications folder after installation.

Check and Install Git

Ensure Git is installed:

git --version

If not installed, install it using Homebrew:

brew install git

3. Install Oh My Zsh

Oh My Zsh enhances the Zsh shell with themes and plugins. Install it with:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Check here.

Configure .zshrc

Edit your .zshrc file:

vim ~/.zshrc

Add useful plugins:

plugins=(git rails ruby)

The default theme is robbyrussell. You can explore other themes here.

Customize iTerm2 Color Scheme

Find and import themes from iTerm2 Color Schemes.

4. Add Zsh Plugins

Enhance your terminal experience with useful plugins.

a. Install zsh-autosuggestions

This plugin provides command suggestions as you type.

Install via Oh My Zsh:

git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

Or install via Homebrew:

brew install zsh-autosuggestions

Add to ~/.zshrc:

plugins=(git rails ruby zsh-autosuggestions)

If installed via Homebrew, add:

source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh

to the bottom of ~/.zshrc.

Restart iTerm2:

exec zsh

b. Install zsh-syntax-highlighting

This plugin highlights commands to distinguish valid syntax from errors.

Install via Oh My Zsh:

git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

Add to .zshrc:

plugins=(git rails ruby zsh-autosuggestions zsh-syntax-highlighting)

Restart iTerm2:

exec zsh

Wrapping Up

Your terminal is now set up for an optimized development experience! With Homebrew, iTerm2, Oh My Zsh, and useful plugins, your workflow will be faster and more efficient.

to be continued …

Setup Nginx, SSL , Firewall | Moving micro-services into AWS EC2 instance – Part 4

Install Nginx proxy server. Nginx also act like a load-balacer which is helpful for the balancing of network traffic.

sudo apt-get update
sudo apt-get install nginx

Commands to stop, start, restart, check status

sudo systemctl stop nginx
sudo systemctl start nginx
sudo systemctl restart nginx

# after making configuration changes
sudo systemctl reload nginx
sudo systemctl disable nginx
sudo systemctl enable nginx

Install SSL – Letsencrypt

Install packages needed for ssl

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx

Install the SSL Certificate:

certbot -d '*.domain.com' -d domain.com --manual --preferred-challenges dns certonly

Your certificate and chain have been saved at:
   /etc/letsencrypt/live/domain.com/fullchain.pem

Your key file has been saved at:
   /etc/letsencrypt/live/domain.com/privkey.pem
SSL certificate auto renewal

Let’s Encrypt’s certificates are valid for 90 days. To automatically renew the certificates before they expire, the certbot package creates a cronjob which will run twice a day and will automatically renew any certificate 30 days before its expiration.

Since we are using the certbot webroot plug-in once the certificate is renewed we also have to reload the nginx service. To do so append –renew-hook “systemctl reload nginx” to the /etc/cron.d/certbot file so as it looks like this:

/etc/cron.d/certbot
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"

To test the renewal process, use the certbot –dry-run switch:

sudo certbot renew --dry-run

Renew your EXPIRED certificate this way:

sudo certbot --force-renewal -d '*.domain.com' -d domain.com --manual --preferred-challenges dns certonly

Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.<domain>.com with the following value:

O3bpxxxxxxxxxxxxxxxxxxxxxxxxxxY4TnNo

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

You need to update the DNS txt record for _acme-challenge.<domain>.com

sudo systemctl restart nginx # restart nginx to take effect

Configure the Firewall

Next, we’ll update our firewall to allow HTTPS traffic.

Check firewall status in the system. If it is inactive enable firewall.

sudo ufw status # check status

# enable firewall
sudo ufw enable
sudo ufw allow ssh
sudo ufw allow OpenSSH

Enable particular ports where your micro-services are running. Example:

sudo ufw allow 4031/tcp # Authentication service
sudo ufw allow 4131/tcp # File service
sudo ufw allow 4232/tcp # Search service

You can delete the ‘Authentication service’ firewall rule by:

sudo ufw delete allow 4031/tcp

Setup Ruby, ruby-build, rbenv-gemset | Conclusion – Moving micro-services into AWS EC2 instance – Part 3

In this post let’s setup Ruby and ruby gemsets for each project, so that your package versions are maintained.

Install ruby-build # ruby-build is a command-line utility for rbenv

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

# Add ruby build path

echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc # OR
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.zshrc

# load it

source ~/.bashrc # OR
source ~/.zshrc


For Mac users – iOS users


# verify rbenv
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-doctor | bash

If you are using zsh add the following to `~/.zshrc`

# rbenv configuration
eval "$(rbenv init -)"
export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)"

Install Ruby 2.5.1 using rbenv

rbenv install 2.5.1

rbenv global 2.5.1 # to make this version as default

ruby -v # must display 2.5.1 if installed correctly

which ruby # must show the fully qualified path of the executable

echo "gem: --no-document" > ~/.gemrc # to skip documentation while installing gem

rbenv rehash # latest version of rbenv apparently don't need this. Nevertheless, lets use it to avoid surprises.

gem env home # See related details

# If a new version of ruby was installed, ensure RubyGems is up to date.
gem update --system --no-document


Install rbenv gemset – https://github.com/jf/rbenv-gemset

git clone git://github.com/jf/rbenv-gemset.git ~/.rbenv/plugins/rbenv-gemset

If you are getting following issue:

fatal: remote error:
  The unauthenticated git protocol on port 9418 is no longer supported.
# Fix
 git clone https://github.com/jf/rbenv-gemset.git ~/.rbenv/plugins/rbenv-gemset

Now clone your project and go inside the project folder -Micro-service folder (say my-project) which has Gemfile in it and do the following commands.

cd my-project

my-project $ rbenv gemset init # NOTE: this will create the gemset under the current ruby version.

my-project $ rbenv gemset list # list all gemsets

my-project $ rbenv gemset active # check this in project folder

my-project $ gem install bundler -v '1.6.0'

my-project $ rbenv rehash

my-project $ bundle install  # install all the gems for the project inside the gemset.

my-project $ rails s -e production # start rails server
my-project $ puma -e production -p 3002 -C config/puma.rb # OR start puma server
# OR start the server you have configured with rails. 

Do this for all the services and see how this is running. The above will install all the gems inside the project gemset that acts like a namespace.

So our aim is to setup all the ruby micro-services in the same machine.

  • I started 10 services together in AWS EC2 (type: t3.small).
  • Database is running in t2.small instance with 2 volumes (EBS) attached.
  • For Background job DB (redis) is running in t2.micro instance.

So for 3 ec2 instance + 2 EBS volumes –$26 + elastic IP addresses ( aws charges some amount – $7.4) 1 month duration, it costs me around $77.8, almost 6k rupees. That means we reduced the aws-cloud cost to half of the previous cost.

Steps to reinstall rvm in ubuntu

Uninstall RVM – do the following

unset GEM_HOME

rvm implode

rm -rf ~/.rvm

sudo rm -rf /usr/share/rvm

sudo rm /etc/profile.d/rvm.sh

sudo rm /etc/rvmrc

sudo rm ~/.rvmrc

vim ~/.zshrc  # or ~/.bash_profile related to machine/software you use and remove rvm related lines

Install RVM:

sudo apt-get install build-essential

unset rvm_path

sudo apt install gnupg2

Goto https://rvm.io/rvm/install and add gpg keys to verify

gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
 
\curl -sSL https://get.rvm.io | bash -s stable

If the following error occurs while adding keys:

➜ gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
gpg: connecting dirmngr at '/run/user/1000/gnupg/S.dirmngr' failed: IPC connect call failed
gpg: keyserver receive failed: No dirmngr

then do:

sudo apt-get update

then you will get some errors regarding the keys, add those keys to following command:

gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB

then do:

\curl -sSL https://get.rvm.io | bash -s stable

Make sure that your ~/.bash_profile or ~/.zshrc file contains the following lines to load rvm to the shell:

# RVM manual script for loading rvm to shell
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" 

After installing check RVM by:

➜ rvm list

# No rvm rubies installed yet. Try 'rvm help install'.

➜ rvm install 2.7.2
Searching for binary rubies, this might take some time.
Found remote file https://rubies.travis-ci.org/ubuntu/18.04/x86_64/ruby-2.7.2.tar.bz2
Checking requirements for ubuntu.
Requirements installation successful.
ruby-2.7.2 - #configure
ruby-2.7.2 - #download
 ..............
No checksum for downloaded archive, recording checksum in user configuration.
ruby-2.7.2 - #validate archive
ruby-2.7.2 - #extract
ruby-2.7.2 - #validate binary
ruby-2.7.2 - #setup
ruby-2.7.2 - #gemset created ~/.rvm/gems/ruby-2.7.2@global
ruby-2.7.2 - #importing gemset ~/.rvm/gemsets/global.gems..................................
ruby-2.7.2 - #generating global wrappers.......
ruby-2.7.2 - #gemset created ~/.rvm/gems/ruby-2.7.2
ruby-2.7.2 - #importing gemsetfile ~/.rvm/gemsets/default.gems evaluated to empty gem list
ruby-2.7.2 - #generating default wrappers.......

➜ rvm list
=* ruby-2.7.2 [ x86_64 ]

# => - current
# =* - current && default
#  * - default

➜ rvm gemset list

gemsets for ruby-2.7.2 (found in ~/.rvm/gems/ruby-2.7.2)
=> (default)
   global

➜ rvm gemset create foobar
ruby-2.7.2 - #gemset created ~/.rvm/gems/ruby-2.7.2@foobar
ruby-2.7.2 - #generating foobar wrappers.......

➜ rvm gemset list              

gemsets for ruby-2.7.2 (found in ~/.rvm/gems/ruby-2.7.2)
=> (default)
   foobar
   global

➜ rvm gemset use foobar
Using ruby-2.7.2 with gemset foobar

➜ rvm gemset list           

gemsets for ruby-2.7.2 (found in ~/.rvm/gems/ruby-2.7.2)
   (default)
=> foobar
   global

➜ rvm list gemsets

rvm gemsets

   ruby-2.7.2 [ x86_64 ]
=> ruby-2.7.2@foobar [ x86_64 ]
   ruby-2.7.2@global [ x86_64 ]

For preserving the gemset for the current directory create .rvmrc file:

vim .rvmrc
# add this: rvm --rvmrc use foobar

If rvm is not loading into the shell after changing the terminal preferences, check the rvm_path env variable.

$rvm_path      
zsh: no such file or directory: /usr/share/rvm

If you don’t have that directory you must change the above path to a correct rvm installed path.

By default rvm installed in this path: ${HOME}/.rvm So you can add this path to rvm_path

Set it like:

export rvm_path="${HOME}/.rvm"

You can add this line into your ~/.zshrc OR ~/.bash_profile file.

You can check rvm env variables and info by:

env | grep rvm  
rvm info

Check ruby version by: ruby -v If ruby is not loading try to add the following line into your bash_profile:

export PATH=~/.rvm/gems/ruby-2.7.2/bin:$PATH # change version: ruby-2.7.2 to your installed version
source ~/.bash_profile OR source ~/.zshrc # whatever you use
ruby -v
 

Rails 5.2.0 API Only application with latest Ruby 2.5.1

Check for the new ruby and rails versions
https://www.ruby-lang.org/en/downloads/
https://rubygems.org/gems/rails/versions

Here we are going to install Ruby – 2.5.1 & Rails – 5.2.0 (API only application)

Get rbenv into action
If you are not installed rbenv, you can install it from here:
https://github.com/rbenv/rbenv
After the installation make sure that, your $PATH has included rbenv/shims path. Else rbenv will not work.

1. $ rbenv install --list # Gets the list of ruby versions available

$ rbenv install 2.5.1

ruby-build: definition not found: 2.5.1

The following versions contain `2.5.1' in the name:
  rbx-2.5.1

See all available versions with `rbenv install --list'.

If the version you need is missing, try upgrading ruby-build:

  brew update && brew upgrade ruby-build

Oops..!

rbenv cannot find the version: 2.5.1

Upgrade ruby-build

Mac OSX:

$ brew upgrade ruby-build --HEAD

Now install ruby 2.5.1

$ rbenv install 2.5.1

Create a new gemset:

Rbenv gemset is a separate script and not coming with rbenv. If you are not installed this, you can install it from here:
https://github.com/jf/rbenv-gemset

$ rbenv gemset create 2.5.1 demo-app
That set up a directory for you in ~/.rbenv/versions/2.5.1/gemsets/demo-app

Set the ruby version to the newest

$ rbenv local 2.5.1

$ rbenv version
=> 2.5.1

    Activate New Gemset


For activating a gemset we need to create a .rbenv-gemsets file in the current directory.

$ touch .rbenv-gemsets
$ echo demo-app > .rbenv-gemsets

Check active gemset:

$ rbenv gemset active

Install Rails 5.2.0 API only Application

$ gem install rails -v '5.2.0'

$ rails -v
Rails 5.2.0

Later we can delete this .rbenv-gemsets file and add a new file named ‘.ruby-gemset’ in the rails project directory. I cannot find any other option for doing this. If anyone know more about this, please give a comment. I appreciate that.

Create a New Rails app

$ rails new demo-app  --api -T # API only skip the testing framework altogether

For Full Rails:

$ rails new demo-app -T -d postgresql # skip the testing framework altogether, uses Postgres Database

-T to exclude Minitest – the default testing framework if you are planning to use RSpec to test your API.

Rspec test framework:
https://github.com/rspec/rspec-rails

You can use the following with Rspec.
Shoulda Matchers:
Collection of testing matchers extracted from Shoulda (http://matchers.shoulda.io)
https://github.com/thoughtbot/shoulda-matchers

Database Cleaner:
Strategies for cleaning databases in Ruby. Can be used to ensure a clean state for testing
https://github.com/DatabaseCleaner/database_cleaner

Faker:
A library for generating fake data such as names, addresses, and phone numbers.
https://github.com/stympy/faker

use option: –no-rdoc –no-ri # skips the documentation

Remove Rbenv Gemset and add Ruby gems file

$ rm .rbenv-gemsets

$ cd demo-app
$ touch .ruby-gemset
$ echo demo-app > .ruby-gemset
$ rails s
=> Booting Puma
=> Rails 5.2.0 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.11.4 (ruby 2.5.1-p57), codename: Love Song
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

Goto http://localhost:3000/

rails-5.2.api-application

Done! Lets go…