Ruby / RoR - Interview Questions
1. What is the difference between includes
, joins
, and preload
in Rails ActiveRecord?
includes
: Eager loads associated records to avoid N+1 queries (usesLEFT OUTER JOIN
or separate queries).joins
: Performs SQLINNER JOIN
but does not load associated data—useful for filtering.preload
: Likeincludes
, but always uses separate queries instead of joins.
Use includes
when you want eager loading and potential filtering; use preload
when you're sure filtering won't occur.
2. How does Rails manage database transactions, and how can you use them effectively?
Rails provides ActiveRecord::Base.transaction
to wrap operations in a DB transaction. If an exception occurs, changes are rolled back.
ActiveRecord::Base.transaction do
user.save!
order.save!
end
Use this to ensure atomicity—either all operations succeed, or none do.
3. Explain how Rails handles background jobs. What tools have you used?
Rails 5+ includes ActiveJob
, an abstraction over background job frameworks. Common adapters: Sidekiq, Resque, DelayedJob.
Example with Sidekiq:
class HardWorker
include Sidekiq::Worker
def perform(user_id)
UserMailer.welcome_email(User.find(user_id)).deliver_now
end
end
Use background jobs for asynchronous, non-blocking tasks—emailing, API calls, data processing.
4. What is a concern in Rails, and when should you use it?
A concern is a module used to share reusable code across models/controllers without inheritance.
# app/models/concerns/trackable.rb
module Trackable
extend ActiveSupport::Concern
included do
has_many :activities
end
end
Use concerns to extract logic that cuts across models—avoid fat models/controllers.
5. How do you optimize performance in large Rails applications?
- Eager load associations to avoid N+1
- Use pagination (
kaminari
,pagy
) - Memoization (
@memoized ||= value
) - Caching: fragment, Russian-doll, low-level
- Avoid unnecessary callbacks and validations
- Use indexes on DB columns
- Avoid heavy queries in views
6. What are service objects in Rails, and why would you use them?
Service objects encapsulate business logic outside controllers/models.
class InvoiceGenerator
def initialize(user)
@user = user
end
def call
Invoice.create(user: @user, total: calculate_total)
end
end
Use them for complex operations, fat controller/model avoidance, and testing isolation.
7. What’s the difference between before_save
and before_create
callbacks?
before_save
: Runs on bothcreate
andupdate
before_create
: Runs only oncreate
Use before_create
when logic should not run during update, e.g., setting UUIDs or default roles.
8. What is strong parameters and why is it important?
Strong parameters (params.require(...).permit(...)
) protect against mass assignment vulnerabilities.
params.require(:user).permit(:email, :name)
Without it, malicious users could update protected attributes like admin: true
.
9. How do you handle multi-environment secrets securely in Rails?
Use Rails credentials (config/credentials.yml.enc
) or ENV variables with gems like dotenv
.
For multiple environments:
EDITOR="vim" bin/rails credentials:edit --environment production
Avoid committing secrets to git. Use environment-based credential stores for CI/CD.
10. Explain the asset pipeline and how it works in Rails
The asset pipeline:
- Combines and minifies assets
- Uses fingerprinting for cache-busting
- Allows use of preprocessors (Sass, CoffeeScript)
- Manifest file controls what gets compiled
Path: app/assets
, lib/assets
, vendor/assets
In Rails 7, asset management shifted toward import maps, ESBuild, or Webpacker.