Toolmingo
Guides19 min read

50 Ruby on Rails Interview Questions (With Answers)

Top Ruby on Rails interview questions with clear answers and code examples — covering MVC, ActiveRecord, routing, performance, testing, and Rails 7/8 features.

Rails interviews test your understanding of convention over configuration, ActiveRecord internals, RESTful design, and how to build maintainable Ruby applications. This guide covers the 50 most common questions — with concise answers and working code examples.

Quick reference

Topic Most asked questions
Ruby fundamentals Symbols, blocks, procs, lambdas, modules
MVC & Rails basics Convention over configuration, request lifecycle
ActiveRecord Associations, scopes, N+1, migrations
Routing RESTful routes, nested resources, concerns
Performance Caching, background jobs, query optimization
Security CSRF, mass assignment, SQL injection
Testing RSpec, FactoryBot, Capybara
Rails 7/8 Turbo, Stimulus, import maps, Hotwire

Ruby fundamentals

1. What is the difference between a symbol and a string in Ruby?

Symbols are immutable, interned identifiers — the same symbol always has the same object ID, making them ideal for hash keys and named constants. Strings are mutable objects with unique object IDs.

:name.object_id == :name.object_id  # true — same object in memory
"name".object_id == "name".object_id  # false — different objects

# Common use: hash keys
user = { name: "Ana", role: :admin }

# Symbols are garbage collected since Ruby 2.2 (dynamic symbols)

2. Explain blocks, procs, and lambdas — and their key differences.

Feature Block Proc Lambda
Object? No Yes (Proc.new) Yes (lambda/->)
Stored? No Yes Yes
Return behaviour Returns from enclosing method Returns from enclosing method Returns from lambda only
Argument checking Loose Loose Strict
# Block — passed to a method, not a standalone object
[1, 2, 3].each { |n| puts n }

# Proc — storable, loose argument handling
double = Proc.new { |x| x * 2 }
double.call(5)  # 10

# Lambda — strict argument checking, own return scope
square = ->(x) { x ** 2 }
square.call(4)  # 16

3. What are Ruby modules used for?

Modules serve two roles: namespacing (grouping constants/classes) and mixins (sharing behaviour without inheritance).

# Namespace
module Payments
  class Invoice; end
  class Receipt; end
end

# Mixin
module Timestampable
  def created_at_human
    created_at.strftime("%B %d, %Y")
  end
end

class Order < ApplicationRecord
  include Timestampable
end

4. What is the difference between include, extend, and prepend?

Method Adds module methods as... Lookup order
include Instance methods After class in ancestor chain
extend Class methods After singleton class
prepend Instance methods Before class (can override)
module Greetable
  def greet = "Hello, I am #{name}"
end

class Person
  include Greetable  # Person instances get #greet
  extend  Greetable  # Person class gets .greet
end

5. What does yield do in Ruby?

yield calls the block passed to a method. block_given? checks if one was supplied.

def measure
  start = Time.now
  result = yield  # executes the block
  puts "Took: #{Time.now - start}s"
  result
end

measure { sleep(0.1); 42 }  # prints elapsed time, returns 42

MVC & Rails basics

6. What does "convention over configuration" mean in Rails?

Rails makes decisions for you — file names map to class names, table names map to model names, directory structure is predefined — so you write less configuration. Deviating is possible but requires explicit setup.

# Convention: model User → table users, file app/models/user.rb
# Convention: controller UsersController → file app/controllers/users_controller.rb
# Convention: views in app/views/users/

7. Describe the Rails request lifecycle.

  1. Router matches URL to a controller action
  2. Middleware stack processes the request (cookies, sessions, logging)
  3. Controller action runs — calls models, sets instance variables
  4. View renders (ERB/Haml) using instance variables
  5. Response is sent back through the middleware stack

8. What is the asset pipeline and how has it changed in Rails 7?

The asset pipeline (Sprockets) bundles CSS and JS. In Rails 7 it was largely replaced:

Rails version JS bundling CSS
≤ 6 Webpacker / Sprockets Sprockets
7 Import maps (default) or jsbundling-rails cssbundling-rails / Propshaft
8 Same + Solid adapters Same

Import maps serve unbundled ES modules — no Node.js build step required for simple apps.

9. Explain Rails' MVC and where business logic belongs.

Layer Responsibility Avoid
Model Data, validations, associations, domain logic HTTP/view concerns
View Presentation only Database queries, business logic
Controller Orchestration — calls models, selects views Business logic (fat controller anti-pattern)
Service Object Complex business operations (not built-in)

Thin controllers + fat models (or service objects) is the Rails way.

10. What are Rails concerns?

Concerns are modules that extract shared model or controller behaviour, living in app/models/concerns/ or app/controllers/concerns/.

# app/models/concerns/searchable.rb
module Searchable
  extend ActiveSupport::Concern

  included do
    scope :search, ->(q) { where("name ILIKE ?", "%#{q}%") }
  end

  def highlight(term)
    name.gsub(term, "<mark>#{term}</mark>")
  end
end

class Product < ApplicationRecord
  include Searchable
end

ActiveRecord

11. What are the ActiveRecord association types?

Association SQL equivalent Use when
belongs_to Foreign key on this table Child model
has_one Foreign key on the other table One-to-one
has_many Foreign key on the other table One-to-many
has_many :through Join table (explicit model) Many-to-many with data on join
has_and_belongs_to_many Pure join table Many-to-many, no join model
has_one :through Join table One-to-one via join
class Author < ApplicationRecord
  has_many :books
  has_many :genres, through: :books
end

class Book < ApplicationRecord
  belongs_to :author
  belongs_to :genre
end

12. What is the N+1 query problem and how do you solve it in Rails?

N+1 occurs when you execute one query to fetch N records, then N more queries for associated data.

# N+1 — 1 + N queries
posts = Post.all
posts.each { |p| puts p.author.name }

# Fix: eager loading
posts = Post.includes(:author)  # 2 queries total
posts = Post.eager_load(:author)  # 1 JOIN query
posts = Post.preload(:author)   # 2 queries (like includes, no JOIN)

Use the bullet gem to detect N+1s automatically in development.

13. Explain ActiveRecord scopes.

Scopes are reusable, chainable query fragments defined on a model.

class Article < ApplicationRecord
  scope :published, -> { where(published: true) }
  scope :recent, -> { order(created_at: :desc) }
  scope :by_author, ->(id) { where(author_id: id) }
end

# Chainable
Article.published.recent.by_author(3)
# SELECT * FROM articles WHERE published = true ORDER BY created_at DESC AND author_id = 3

14. What is the difference between destroy and delete in ActiveRecord?

Method Callbacks Associations
destroy Runs before_destroy, after_destroy Handles dependent: :destroy
delete No callbacks No cascade — raw SQL DELETE
destroy_all Callbacks for each record
delete_all No callbacks Single SQL query

15. How do Rails migrations work?

Migrations are version-controlled database schema changes stored in db/migrate/.

rails generate migration AddEmailToUsers email:string:index
class AddEmailToUsers < ActiveRecord::Migration[7.2]
  def change
    add_column :users, :email, :string
    add_index  :users, :email, unique: true
  end
end

rails db:migrate runs pending migrations; rails db:rollback reverses the last one. The db/schema.rb always reflects the current state.

16. What is counter_cache and when should you use it?

counter_cache keeps a cached count column updated automatically, avoiding COUNT(*) queries.

class Comment < ApplicationRecord
  belongs_to :post, counter_cache: true  # increments posts.comments_count
end

# Migration needed:
add_column :posts, :comments_count, :integer, default: 0, null: false

# Usage — no extra query
post.comments_count  # reads the cached integer

17. Explain validates vs database constraints.

Model validation Database constraint
Location Ruby code Database level
Enforced by Rails before save DB always
Error display model.errors ActiveRecord::StatementInvalid
Bypass risk Yes (raw SQL, update_column) No
Best practice Both — validate in model AND add DB constraint
# Both
class User < ApplicationRecord
  validates :email, presence: true, uniqueness: true
end

# Migration
add_index :users, :email, unique: true

18. What are callbacks in ActiveRecord and what are the risks?

Callbacks run at specific points in a model's lifecycle: before_validation, after_create, before_destroy, etc.

class Order < ApplicationRecord
  after_create :send_confirmation_email

  private

  def send_confirmation_email
    OrderMailer.confirmation(self).deliver_later
  end
end

Risks: Callbacks create hidden side effects, make testing harder, and can cause unintended actions when records are created in tests. Consider service objects for complex logic.


Routing

19. What does resources generate in Rails routing?

resources :articles
# GET    /articles          → index
# GET    /articles/new      → new
# POST   /articles          → create
# GET    /articles/:id      → show
# GET    /articles/:id/edit → edit
# PATCH  /articles/:id      → update
# DELETE /articles/:id      → destroy

20. How do you define nested resources and when should you avoid deep nesting?

resources :authors do
  resources :books  # /authors/:author_id/books/:id
end

Rails recommends max 1 level of nesting. For deeper relationships, use shallow: or only nest the collection routes.

resources :authors do
  resources :books, shallow: true
  # shallow generates /books/:id instead of /authors/:author_id/books/:id
end

21. What is the difference between member and collection routes?

resources :photos do
  member   { get :preview }    # /photos/:id/preview  (single record)
  collection { get :search }   # /photos/search       (no ID)
end

22. What are route constraints?

Constraints restrict which requests match a route — by format, subdomain, or custom logic.

constraints(subdomain: "api") do
  namespace :api do
    resources :users
  end
end

get '/users/:id', to: 'users#show', constraints: { id: /\d+/ }

Controllers & Views

23. What is strong parameters and why is it needed?

Strong parameters prevent mass assignment vulnerabilities by requiring explicit whitelisting of permitted attributes.

class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    # ...
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password)
    # :admin, :role are NOT permitted — cannot be set via form
  end
end

Without this, a malicious user could POST user[admin]=true.

24. Explain the before_action filter.

before_action runs a method before specified controller actions — common for authentication, loading shared resources, setting locale.

class ArticlesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_article, only: [:show, :edit, :update, :destroy]

  private

  def set_article
    @article = Article.find(params[:id])
  end
end

25. What are Rails helpers and decorators (Draper)?

Helpers are modules for view-level utility methods available in templates. Decorators (Draper gem) wrap model objects with presentation logic.

# Helper — global, in any view
module ApplicationHelper
  def format_price(cents)
    number_to_currency(cents / 100.0)
  end
end

# Draper decorator — model-specific presentation
class ProductDecorator < Draper::Decorator
  delegate_all

  def display_price
    h.number_to_currency(model.price_cents / 100.0)
  end
end

Performance

26. How does Rails caching work?

Rails provides multiple caching layers:

Type What it caches How
Page caching Full HTTP response Nginx serves static file
Action caching Controller action output Middleware
Fragment caching Parts of views cache do ... end in ERB
Low-level caching Arbitrary data Rails.cache.fetch
HTTP caching ETags / Last-Modified fresh_when / stale?
# Fragment cache in a view
<% cache @product do %>
  <%= render @product %>
<% end %>

# Low-level
user_count = Rails.cache.fetch("user_count", expires_in: 1.hour) do
  User.count
end

27. What is Russian Doll caching?

Nested fragment caches where each cache key includes the parent's timestamp — a change to a child automatically busts the parent.

# Parent cache key includes child updated_at
<% cache @post do %>
  <%= @post.title %>
  <% cache @post.comments do %>
    <%= render @post.comments %>
  <% end %>
<% end %>

28. How do you run background jobs in Rails?

Active Job provides a unified interface; adapters (Sidekiq, Solid Queue, GoodJob) do the actual processing.

class WelcomeEmailJob < ApplicationJob
  queue_as :default

  def perform(user_id)
    user = User.find(user_id)
    UserMailer.welcome(user).deliver_now
  end
end

# Enqueue
WelcomeEmailJob.perform_later(user.id)
WelcomeEmailJob.set(wait: 1.hour).perform_later(user.id)

Rails 8 ships Solid Queue as the default — uses the database as a queue, no Redis required for simple setups.

29. How do you detect and fix slow queries in Rails?

# Development: log slow queries
# config/environments/development.rb
config.log_level = :debug  # All SQL logged

# bullet gem for N+1 detection
# rack-mini-profiler for request profiling

# In console
User.where(active: true).explain  # show query plan

# Fix: add index
add_index :users, :active
add_index :orders, [:user_id, :created_at]  # composite

30. What is connection pooling in Rails?

Rails maintains a pool of database connections (default: 5 per process) to avoid the overhead of creating a new connection per request.

# config/database.yml
production:
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  checkout_timeout: 5

With Puma (multiple threads), set pool equal to RAILS_MAX_THREADS.


Security

31. How does Rails protect against CSRF?

Rails includes an authenticity token in forms and verifies it on non-GET requests. The protect_from_forgery method (included in ApplicationController by default) raises ActionController::InvalidAuthenticityToken if the token is missing or invalid.

# Automatically added to forms by form_with / form_for
<input type="hidden" name="authenticity_token" value="..." />

# For API controllers (token-based auth)
class ApiController < ActionController::API
  # protect_from_forgery not included in ActionController::API
end

32. What is SQL injection and how does Rails prevent it?

ActiveRecord uses parameterized queries by default. String interpolation in WHERE clauses is dangerous.

# VULNERABLE — never do this
User.where("name = '#{params[:name]}'")

# Safe — parameterized
User.where(name: params[:name])
User.where("name = ?", params[:name])
User.where("name = :name", name: params[:name])

33. What are permitted/forbidden attributes (mass assignment)?

See question 23. In addition: use attr_readonly for truly immutable attributes and avoid update_columns (bypasses validations and callbacks).

34. How do you store secrets in Rails?

Rails provides credentials encrypted with a master key:

rails credentials:edit  # opens encrypted credentials.yml.enc
# Inside credentials
database_password: super_secret
stripe:
  secret_key: sk_live_...
# Access
Rails.application.credentials.stripe[:secret_key]
Rails.application.credentials.database_password

The master key lives in config/master.key (not committed) or the RAILS_MASTER_KEY env var.


Testing

35. What testing frameworks are used with Rails?

Framework Role
RSpec Describe/it BDD test syntax (most popular)
Minitest Built-in Rails test framework
FactoryBot Test data factories (replaces fixtures)
Faker Fake data generation
Capybara Integration / system tests (browser simulation)
WebMock / VCR Stub HTTP requests
SimpleCov Test coverage

36. Show a basic RSpec model spec.

# spec/models/user_spec.rb
require "rails_helper"

RSpec.describe User, type: :model do
  describe "validations" do
    it { is_expected.to validate_presence_of(:email) }
    it { is_expected.to validate_uniqueness_of(:email).case_insensitive }
  end

  describe "associations" do
    it { is_expected.to have_many(:posts).dependent(:destroy) }
  end

  describe "#full_name" do
    it "joins first and last name" do
      user = build(:user, first_name: "Ana", last_name: "Lopes")
      expect(user.full_name).to eq("Ana Lopes")
    end
  end
end

37. What is a FactoryBot factory and how does it differ from fixtures?

# spec/factories/users.rb
FactoryBot.define do
  factory :user do
    sequence(:email) { |n| "user#{n}@example.com" }
    first_name { Faker::Name.first_name }
    last_name  { Faker::Name.last_name }
    password   { "password123" }

    trait :admin do
      role { :admin }
    end
  end
end

# Usage
user  = create(:user)          # persisted
admin = create(:user, :admin)  # with trait
guest = build(:user)           # not persisted

Factories are code (flexible, composable); fixtures are static YAML files.

38. How do you write a request spec (integration test)?

# spec/requests/articles_spec.rb
RSpec.describe "Articles", type: :request do
  let(:user) { create(:user) }

  describe "GET /articles" do
    it "returns a list of articles" do
      create_list(:article, 3, user: user)
      get articles_path
      expect(response).to have_http_status(:ok)
      expect(response.body).to include("articles")
    end
  end

  describe "POST /articles" do
    context "with valid params" do
      it "creates an article" do
        sign_in user
        expect {
          post articles_path, params: { article: { title: "Hello", body: "World" } }
        }.to change(Article, :count).by(1)
        expect(response).to redirect_to(article_path(Article.last))
      end
    end
  end
end

Rails 7 / 8 features

39. What is Hotwire (Turbo + Stimulus)?

Hotwire is Rails 7's default frontend approach — HTML-over-the-wire instead of JSON + heavy JS framework.

Component Purpose
Turbo Drive AJAX page navigation without full reload
Turbo Frames Update isolated page regions
Turbo Streams Server-pushed partial updates (via WebSocket or SSE)
Stimulus Lightweight JS controllers for sprinkles of behaviour
<%# Turbo Frame — only this section reloads %>
<%= turbo_frame_tag "comment_form" do %>
  <%= render "comments/form", post: @post %>
<% end %>

40. What is Action Cable?

Action Cable integrates WebSockets into Rails — used for real-time features: chat, notifications, live counters.

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  def subscribed
    stream_from "chat_#{params[:room]}"
  end

  def speak(data)
    ActionCable.server.broadcast("chat_#{params[:room]}", message: data["message"])
  end
end

41. What's new in Rails 8?

Feature Description
Solid Queue Database-backed job queue (default, no Redis)
Solid Cache Database-backed cache store
Solid Cable Database-backed Action Cable adapter
Authentication generator rails generate authentication — session-based auth out of the box
Kamal 2 Deployment to bare VPS via Docker
Asset improvements Propshaft as default for simple apps

42. What are import maps?

Import maps (default in Rails 7+) allow using ES modules in browsers without a JavaScript bundler — the browser resolves bare module specifiers via a JSON map.

<script type="importmap">
{
  "imports": {
    "@hotwired/turbo-rails": "/assets/turbo.js",
    "stimulus": "/assets/stimulus.js"
  }
}
</script>

No Webpack, no Node.js build step needed for simple apps.


Architecture & patterns

43. What are service objects and when should you use them?

Service objects encapsulate complex business operations that don't belong in models or controllers.

# app/services/user_registration_service.rb
class UserRegistrationService
  def initialize(params)
    @params = params
  end

  def call
    ActiveRecord::Base.transaction do
      user = User.create!(@params)
      WelcomeEmailJob.perform_later(user.id)
      SubscriptionService.new(user).create_trial!
      user
    end
  end
end

# Controller
def create
  user = UserRegistrationService.new(user_params).call
  redirect_to user, notice: "Welcome!"
rescue ActiveRecord::RecordInvalid => e
  render :new, status: :unprocessable_entity
end

44. What is STI (Single Table Inheritance)?

STI stores multiple model classes in one database table with a type column.

# One table: vehicles (type, speed, capacity, ...)
class Vehicle < ApplicationRecord; end
class Car < Vehicle; end
class Truck < Vehicle; end
class Motorcycle < Vehicle; end

Car.create!(speed: 200)
# INSERT INTO vehicles (type, speed) VALUES ('Car', 200)

Use STI when subclasses share most columns. Use separate tables (polymorphic associations or separate models) when they differ significantly.

45. Explain polymorphic associations.

A polymorphic association lets one model belong to multiple other models via a single association.

class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
end

class Article < ApplicationRecord
  has_many :comments, as: :commentable
end

class Video < ApplicationRecord
  has_many :comments, as: :commentable
end

# Migration
create_table :comments do |t|
  t.text       :body
  t.references :commentable, polymorphic: true  # commentable_type + commentable_id
end

46. What is the decorator pattern in Rails context?

The decorator (often using the Draper gem or plain Ruby objects) separates presentation logic from domain logic.

class UserDecorator < SimpleDelegator
  def display_name
    [first_name, last_name].compact.join(" ").presence || email
  end

  def avatar_url
    gravatar_hash = Digest::MD5.hexdigest(email.downcase)
    "https://www.gravatar.com/avatar/#{gravatar_hash}"
  end
end

decorated = UserDecorator.new(user)
decorated.display_name  # delegates to user for unknown methods

Common interview scenarios

47. How would you design a multi-tenant Rails app?

Two main approaches:

Approach How Pros / Cons
Shared schema tenant_id on every table; global scope via default_scope or acts_as_tenant Simpler, less overhead; data isolation is logic-level
Separate schemas (PostgreSQL) One schema per tenant; Apartment gem switches schemas per request Strong isolation; more complex migrations
# Shared schema with acts_as_tenant
class ApplicationController < ActionController::Base
  set_current_tenant_through_filter
  before_action :set_tenant

  def set_tenant
    current_tenant = Account.find_by(subdomain: request.subdomain)
    set_current_tenant(current_tenant)
  end
end

48. How would you add authentication to a Rails app?

Option Description
Rails 8 generator rails generate authentication — built-in, session-based
Devise Full-featured gem: registration, confirmation, 2FA, omniauth
Rodauth More secure, Ruby idiomatic, less Rails-magic
JWT (API) Stateless — use devise-jwt or custom before_action
# Rails 8 — generates User, Session, Password models + controllers
rails generate authentication
rails db:migrate

49. How do you handle file uploads in Rails?

# Active Storage — built-in since Rails 5.2
class User < ApplicationRecord
  has_one_attached :avatar
  has_many_attached :documents
end

# Controller
def update
  @user.update(user_params)
  # params[:user][:avatar] is automatically handled
end

# View
<%= image_tag @user.avatar if @user.avatar.attached? %>

Files can be stored locally, on S3 (via activestorage-s3), or GCS. Use Direct Upload for large files.

50. What are common Rails anti-patterns?

Anti-pattern Problem Fix
Fat controller Business logic in controllers Move to service objects / models
Fat model God model with 2000+ lines Extract concerns, service objects, query objects
N+1 queries Hidden in views includes/eager_load + bullet gem
Callbacks for side effects Hidden coupling, hard to test Service objects
update_column / save(validate: false) Bypasses validations Understand when appropriate; audit usage
Rendering JSON in controllers manually Maintenance burden Jbuilder / serializers (blueprinter)
Time-based tests Flaky travel_to / freeze_time in ActiveSupport
Long-running synchronous jobs Request timeout perform_later via Active Job

Common mistakes

Mistake Why it's wrong Correct approach
User.find in a loop N queries Use where(id: ids) to batch-fetch
Using default_scope Global scope causes surprising behaviour everywhere Explicit named scopes
Business logic in views Untestable, violates SRP Helpers or decorators
Not using transactions Partial data on failure ActiveRecord::Base.transaction
rescue Exception Catches SignalException, SystemExit rescue StandardError
Exposing raw IDs in URLs Enumerable, predicts resource IDs UUIDs or hashid
Synchronous email sending Blocks requests deliver_later

Rails vs other frameworks

Feature Ruby on Rails Django (Python) Laravel (PHP) Spring Boot (Java)
Philosophy Convention over config Explicit is better Convention + config Annotations-heavy
ORM ActiveRecord Django ORM Eloquent JPA / Hibernate
Migrations Built-in Built-in Built-in Flyway / Liquibase
Background jobs Active Job + Sidekiq Celery Queue / Horizon Spring Batch
Admin panel ActiveAdmin / Administrate Django Admin Nova / Filament
API support ActionController::API DRF Sanctum / Passport Spring MVC
Asset handling Sprockets / Import Maps WhiteNoise Vite/Mix Spring Resources
Learning curve Medium (Ruby + conventions) Medium Low-medium High

FAQ

Q: Is Ruby on Rails still worth learning in 2025?
Yes. Rails powers large-scale apps (Shopify, GitHub, Basecamp, Airbnb historically). Its developer productivity is unmatched for CRUD apps, and Rails 8 with Hotwire removes the need for a separate frontend framework in many cases.

Q: What's the difference between find and find_by?
find takes an ID (or array of IDs) and raises ActiveRecord::RecordNotFound if not found. find_by takes conditions and returns nil if not found — use it when the record may not exist.

Q: How does Rails autoloading work?
Rails uses Zeitwerk (since Rails 6) for constant autoloading — file names must match class names exactly (app/models/user.rbUser). Files are loaded on demand; eager_load! in production loads everything upfront.

Q: What is the difference between render and redirect_to?
render sends a response immediately (renders a view without a new request). redirect_to sends an HTTP 302/301 and the browser makes a new GET request. Use redirect_to after successful mutations (PRG pattern) to prevent double-form-submission.

Q: What is touch in ActiveRecord?
touch updates the updated_at timestamp of a record (or specified columns), which is used to bust associated cache keys in Russian Doll caching.

Q: How do you upgrade a Rails app to a new major version?

  1. Update the Rails version in Gemfile incrementally (e.g., 6.0 → 6.1 → 7.0 → 7.1)
  2. Run rails app:update to update config files
  3. Fix deprecation warnings one version at a time
  4. Update gems (bundle update) and check compatibility
  5. Run full test suite after each step

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools