Beginner Level (0–1 Years)

1. What is the difference between `render` and `redirect_to` in Rails controllers?

Answer:

`render` displays a view template without changing the URL or starting a new request-response cycle. `redirect_to` sends an HTTP redirect response to the browser, initiating a new request and updating the URL.

2. How does Rails handle database transactions by default in ActiveRecord?

Answer:

By default, ActiveRecord wraps each `save`, `create`, or `update` operation in its own transaction. To group multiple operations in a single transaction, use:

ActiveRecord::Base.transaction do
  user.save!
  profile.save!
end

3. What’s the difference between `update` and `update_attributes` in Rails?

Answer:

In Rails 5 and above, `update` and `update_attributes` are aliases, both updating model attributes and saving to the database. However, `update_attributes` is deprecated in Rails 6.1 and later, with `update` being the preferred method for consistency and clarity.

4. Why might a Rails scope fail silently when chained with other scopes?

Answer:

A scope may return `nil` instead of an ActiveRecord::Relation if it includes conditional logic or an explicit `return`. This breaks method chaining, causing subsequent scopes to fail silently. For example:

scope :active, -> { return nil if Time.now.hour < 12; where(active: true) }

To fix, always return a relation:

scope :active, -> { where(active: true) }

5. Explain the concept of “fat models, skinny controllers” in Rails. Why is it recommended?

Answer:

This convention encourages placing business logic in models, keeping controllers focused on handling HTTP requests and responses. It promotes testability, code reuse, and clear separation of concerns.

6. What does `before_action` do and when should it be avoided?

Answer:

`before_action` runs a specified method before controller actions. Avoid it when it causes side effects or obscures critical logic, as it can make the controller’s flow harder to follow and test.

7. How can mass assignment be a security risk in Rails?

Answer:

Mass assignment without strong parameters allows malicious users to update sensitive attributes (e.g., `admin: true`). Rails requires whitelisting parameters using:

params.require(:user).permit(:email, :password)

8. How does Rails determine which layout to render?

Answer:

Rails infers the layout from the controller’s name (e.g., `application.html.erb` for ApplicationController) unless overridden with `layout “custom”` or a dynamic method like `layout :layout_by_resource`.

9. What’s the purpose of the `config/database.yml` file?

Answer:

It specifies database configurations (e.g., adapter, username, password, host) for different Rails environments (development, test, production).

10. When would using `.save!` be preferred over `.save`?

Answer:

Use `.save!` to raise an exception if the save fails, which is useful in transactions or tests where you need to ensure the operation succeeds or fails explicitly.

11. What happens if a migration fails halfway through?

Answer:

If the database supports transactions, Rails wraps migrations in a transaction, rolling back changes if the migration fails, leaving the schema unchanged.

12. Can you call a model method from a view? Should you?

Answer:

Yes, you can call model methods in views, but they should be limited to presentation logic (e.g., `user.full_name`). Avoid complex business logic or database queries in views.

13. What is the N+1 query problem and how can you avoid it in Rails?

Answer:

The N+1 query problem occurs when Rails queries associated records individually. Avoid it with `includes`:

User.includes(:posts).each do |user|
  user.posts.each do |post|
    puts post.title
  end
end

14. What’s the difference between `has_many :through` and `has_and_belongs_to_many`?

Answer:

`has_many :through` uses a join model with additional attributes or validations. `has_and_belongs_to_many` uses a simple join table without a model, suitable for basic relationships.

15. What does `dependent: :destroy` do? Are there risks?

Answer:

It destroys associated records when the parent is destroyed. Risks include accidental data loss or performance issues when deleting many records.

16. What are RESTful routes in Rails, and how does the `resources` method work?

Answer:

RESTful routes follow a standard pattern for CRUD operations (e.g., index, show, create, update, destroy). The `resources :users` method generates seven standard routes, like `GET /users` (index) and `POST /users` (create). Check routes with `rails routes`.

17. What are strong parameters and why are they needed?

Answer:

Strong parameters prevent mass assignment vulnerabilities by requiring explicit whitelisting of attributes in controllers, e.g.:

params.require(:user).permit(:email, :password)

18. What is the purpose of `.erb` files in Rails views?

Answer:

`.erb` (Embedded Ruby) files combine HTML with Ruby code to render dynamic content in Rails views, enabling dynamic web pages.

19. What are partials in Rails views, and how are they used?

Answer:

Partials are reusable view fragments, named with an underscore (e.g., `_form.html.erb`), rendered with `render partial: ‘form’`. They promote DRY code by reusing view components.

20. How do you manage sensitive data like API keys in a Rails application?

Answer:

Use environment variables with `ENV[‘API_KEY’]` to access sensitive data securely. Gems like `dotenv-rails` load variables from a `.env` file, or set them in the server environment.

21. Can you use `self` inside a Rails model method? What does it refer to?

Answer:

Yes, `self` in an instance method refers to the current model instance. In a class method (e.g., `def self.method`), it refers to the class itself.

22. What’s the difference between `pluck` and `select` in ActiveRecord?

Answer:

`pluck` retrieves specific columns as an array (e.g., `User.pluck(:email)`), bypassing model instantiation. `select` loads model objects with specified attributes only.

23. How can you validate uniqueness in Rails, and what is a potential caveat?

Answer:

Use `validates :email, uniqueness: true` to ensure unique values. Without a database-level unique index, race conditions may allow duplicates.

24. What’s a polymorphic association and when would you use it?

Answer:

A polymorphic association allows a model to belong to multiple models via a single association, using `something_type` and `something_id`. Example: A `Comment` model can belong to `Post` or `Photo`.

25. What are some common ActiveRecord validations besides uniqueness?

Answer:

Common validations include `presence` (`validates :name, presence: true`), `length` (`validates :password, length: { minimum: 6 }`), and `numericality` (`validates :age, numericality: { only_integer: true }`).


👋 Need top Ruby on Rails developers for your project? Interview this week!

Fill out the form to book a call with our team. We’ll match you to the top developers who meet your requirements, and you’ll be interviewing this week!

Request for Service


Intermediate Level (1–3 Years)

1. What are concerns in Rails and when should you use them?

Answer:

Concerns are modules that extract shared logic from models or controllers, promoting DRY code. Use them when multiple classes share methods without inheritance. Example:

# app/models/concerns/auditable.rb
module Auditable
  extend ActiveSupport::Concern

  included do
    before_save :audit_log
  end

  def audit_log
    # logging logic
  end
end

# app/models/user.rb
class User < ApplicationRecord
  include Auditable
end

2. Explain how Rails handles CSRF protection. How can it be bypassed?

Answer:

Rails embeds a CSRF token in forms and verifies it on POST/PUT/DELETE requests. Bypassing it requires disabling protection with `skip_before_action :verify_authenticity_token`, which should only be done for API endpoints with alternative security.

3. What does the counter cache feature do in Rails, and why is it preferred over counting associated records directly?

Answer:

`counter_cache` stores the count of associated records in a column (e.g., `posts_count`), avoiding costly `.count` queries. Example:

class Comment < ApplicationRecord
  belongs_to :post, counter_cache: true
end

4. How can you optimize a slow ActiveRecord query?

Answer:

Use `includes` for eager loading, select specific columns, add database indexes, and avoid N+1 queries. Paginate or batch-process large datasets to reduce memory usage.

5. How do the methods for joining and preloading associations differ in ActiveRecord?

Answer:

`joins` performs an SQL JOIN without preloading data. `includes` may use a JOIN or separate queries for eager loading. `preload` always uses separate queries to load associations.

6. What are service objects in Rails, and when should you use them?

Answer:

Service objects encapsulate complex business logic outside models or controllers. They’re plain Ruby classes in `app/services`. Example:

# app/services/user_signup.rb
class UserSignup
  def initialize(user_params)
    @params = user_params
  end

  def call
    user = User.new(@params)
    user.save
  end
end

7. What is STI (Single Table Inheritance) in Rails and what are its drawbacks?

Answer:

STI stores multiple model classes in one table using a `type` column. Drawbacks include many nullable columns for divergent subclasses and potential performance issues.

8. How can you test a controller action in Rails without hitting the database?

Answer:

Use mocks or stubs in RSpec to avoid database calls. Example:

allow(User).to receive(:find).and_return(double(User, id: 1, name: "Test"))

9. How do you implement token-based authentication for a Rails API?

Answer:

Use `devise-jwt` or custom JWT authentication. Example:

class ApplicationController < ActionController::API
  before_action :authenticate_user

  def authenticate_user
    token = request.headers['Authorization']&.split(' ')&.last
    decoded = JWT.decode(token, Rails.application.credentials.secret_key_base)
    @current_user = User.find(decoded[0]['user_id'])
  rescue
    render json: { error: 'Unauthorized' }, status: :unauthorized
  end
end

10. How can you implement soft deletes in Rails?

Answer:

Use a `deleted_at` column or the `paranoia` gem. Example:

scope :active, -> { where(deleted_at: nil) }

def soft_delete
  update(deleted_at: Time.current)
end

11. How does `accepts_nested_attributes_for` work in Rails?

Answer:

It allows nested attributes to be saved via a parent form. Example:

class User < ApplicationRecord
  has_one :profile
  accepts_nested_attributes_for :profile
end

Form inputs like `user[profile_attributes][bio]` update the profile.

12. How does `validates_associated` work and when is it needed?

Answer:

It validates associated records before saving the parent. Example:

class Order < ApplicationRecord
  has_many :line_items
  validates_associated :line_items
end

Useful for ensuring nested records are valid.

13. What is `delegate` in Rails and how is it used?

Answer:

It forwards method calls to associated models. Example:

class User < ApplicationRecord
  has_one :profile
  delegate :bio, to: :profile
end

`user.bio` calls `user.profile.bio`.

14. How do the form-building methods in Rails differ in their usage and behavior?

Answer:

`form_for` is older, tied to model objects. `form_with` is more flexible, supporting model or URL-based forms, and does not enable AJAX by default. Example:

<%= form_with model: @user, url: users_path %>

`form_with` is preferred in Rails 5.1+.

15. What are the different caching strategies in Rails, and when would you use them?

Answer:

Rails supports page caching (static pages), action caching (controller-level), fragment caching (view snippets), and low-level caching (e.g., `Rails.cache`). Example:

<% cache @post do %>
  <%= render @post %>
<% end %>

Use fragment caching for dynamic content, page caching for static pages.

16. What are callbacks in ActiveRecord and what are some pitfalls of overusing them?

Answer:

Callbacks (`before_save`, `after_create`) run at lifecycle events. Overuse can hide logic, complicate tests, and cause tight coupling.

17. How does the enumeration feature work in ActiveRecord?

Answer:

`enum` maps symbolic names to integers. Example:

enum status: { pending: 0, approved: 1, rejected: 2 }

Provides methods like `model.approved!` or `model.pending?`.

18. How does Action Cable work in Rails, and what is a simple use case?

Answer:

Action Cable uses WebSockets for real-time features via channels. Example use case: a chat app broadcasting messages:

class MessagesChannel < ApplicationCable::Channel
  def subscribed
    stream_from "messages"
  end
end
ActionCable.server.broadcast("messages", { text: message.text })

19. How would you create a custom rake task in Rails?

Answer:

Create a file in `lib/tasks/`:

namespace :custom do
  desc "Say hello"
  task hello: :environment do
    puts "Hello from Rake"
  end
end

Run with `rails custom:hello`.

20. What’s the difference between `has_secure_password` and manual password hashing?

Answer:

`has_secure_password` uses `bcrypt` for hashing, validations, and authentication. Manual hashing requires more code and is error-prone.

21. What is the purpose of `rails credentials:edit` and how is it different from environment variables?

Answer:

`rails credentials:edit` manages encrypted secrets in `config/credentials.yml.enc`, safe for version control. Environment variables are external, set by the server. Both store secrets, but credentials are centralized and encrypted.

22. How does `render partial:` differ from regular `render` in views?

Answer:

`render partial:` renders a partial template (prefixed with `_`). Regular `render` can render full or partial templates. Example:

<%= render partial: "user", locals: { user: @user } %>

23. What is a migration rollback and how do you perform one?

Answer:

A rollback undoes a migration. Example:

rails db:rollback

Rollback multiple steps:

rails db:rollback STEP=3

24. How does the `respond_to` block work in Rails controllers?

Answer:

It handles different request formats:

respond_to do |format|
  format.html
  format.json { render json: @user }
end

Used for APIs or multi-format views.

25. How do the callbacks that run before validation differ from those that run before saving in ActiveRecord?

Answer:

`before_validation` runs before validations. `before_save` runs after validations pass but before saving. Use `before_validation` for defaults, `before_save` for persistence logic.

26. How can you manually trigger validations on a Rails model?

Answer:

Use:

model.valid?

Populates `errors` without saving. Check with `model.errors.full_messages`.

27. What is a join table, and how is it different from a join model?

Answer:

A join table connects models in `has_and_belongs_to_many` without a model class. A join model (`has_many :through`) has a class with attributes and validations.

28. How do you add database indexes to improve query performance in Rails?

Answer:

Add indexes in migrations:

class AddIndexToUsersEmail < ActiveRecord::Migration[7.0]
  def change
    add_index :users, :email, unique: true
  end
end

Use composite or partial indexes for complex queries.

29. How do you eager load multiple nested associations?

Answer:

Use nested `includes`:

Post.includes(:comments, comments: :user)

Preloads comments and their users, avoiding N+1 queries.

30. What does the `rails routes` command show and how can you filter it?

Answer:

Shows all routes. Filter with:

rails routes | grep users

Or:

rails routes -c Users

31. How do routes that apply to a resource collection differ from those that apply to a specific resource in Rails?

Answer:

`collection` routes act on the resource (no ID), `member` routes act on a specific resource (ID). Example:

resources :posts do
  collection do
    get :search
  end
  member do
    get :preview
  end
end

Creates `/posts/search` and `/posts/:id/preview`.

32. How does the batch processing method for ActiveRecord queries improve performance compared to iterating over all records?

Answer:

`find_each` batches records (default 1000), reducing memory usage:

User.find_each do |user|
  # process user
end

33. How does the Rails time zone-aware method for current time differ from the standard Ruby time method?

Answer:

`Time.now` uses system time, ignoring Rails time zone. `Time.current` respects the app’s time zone.

34. What is a concern when using methods that update or delete multiple records directly in ActiveRecord?

Answer:

They skip validations and callbacks, risking data inconsistencies.

35. What is the purpose of specifying the inverse relationship in ActiveRecord associations?

Answer:

It defines inverse relationships for caching and query efficiency:

has_many :books, inverse_of: :author

Ensures object references sync correctly.

36. How does Rails handle parameter access with different key types in controllers?

Answer:

`params` uses `HashWithIndifferentAccess`, allowing string or symbol keys:

params[:email] == params["email"]

37. How would you implement a custom validator in Rails?

Answer:

Create a validator in `app/validators`:

class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value =~ URI::MailTo::EMAIL_REGEXP
      record.errors.add(attribute, "is not a valid email")
    end
  end
end
validates :email, email: true

38. What are helper methods and how are they different from view partials?

Answer:

Helpers are Ruby methods for view logic or formatting. Partials are reusable templates. Example helper:

def format_price(amount)
  number_to_currency(amount)
end

39. What is `turbo` in Rails 7 and how does it change form behavior?

Answer:

Turbo (Hotwire) enhances navigation with Turbo Drive. Forms use Turbo Frames or Streams if configured (e.g., `data-turbo-stream`). Disable with:

<%= form_with model: @user, data: { turbo: false } %>

40. How would you handle different environments (dev/test/prod) in configuration?

Answer:

Use `config/environments/`, `Rails.env` checks, or credentials per environment.

41. How do the methods for creating associated records in memory versus saving them immediately differ in Rails?

Answer:

`build` creates an unsaved object:

user.posts.build(title: "Draft")

`create` saves it:

user.posts.create(title: "Draft")

42. How can you rescue from exceptions at the controller level?

Answer:

Use `rescue_from`:

class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, with: :not_found

  def not_found
    render plain: "Not Found", status: 404
  end
end

43. What’s the purpose of `ActiveSupport::Concern` and why is it better than a plain module?

Answer:

`ActiveSupport::Concern` simplifies mixins with `included` and `class_methods` blocks, avoiding dependency issues.

44. What does `config.force_ssl = true` do in a Rails application?

Answer:

It redirects HTTP to HTTPS, sets secure headers, and enables secure cookies in production.

45. What is the difference between `ApplicationJob`, `ActiveJob::Base`, and background job adapters?

Answer:

`ApplicationJob` inherits from `ActiveJob::Base` for app-wide job settings. Example:

class ApplicationJob < ActiveJob::Base
  queue_as :default
end

Adapters (e.g., Sidekiq) handle queuing.

46. How would you handle file uploads in a Rails app?

Answer:

Use `ActiveStorage`:

has_one_attached :avatar

Or gems like CarrierWave for advanced features.

47. What is the role of `content_for` in views and how is it used?

Answer:

`content_for` defines content blocks for layouts:

<% content_for :title do %>
  My Page Title
<% end %>
<%= yield :title %>

48. How can you use Arel to build complex ActiveRecord queries?

Answer:

Arel builds SQL via AST:

users = User.arel_table
query = users.where(users[:age].gt(18)).project(users[:name])
User.find_by_sql(query.to_sql)

49. How do you write a feature spec in RSpec for a Rails app?

Answer:

Use Capybara for feature specs:

RSpec.feature "User login", type: :feature do
  scenario "with valid credentials" do
    user = create(:user, email: "test@example.com", password: "password")
    visit new_user_session_path
    fill_in "Email", with: user.email
    fill_in "Password", with: "password"
    click_button "Log in"
    expect(page).to have_content("Signed in successfully")
  end
end

50. How would you handle versioned APIs in a Rails application?

Answer:

Namespace routes:

namespace :api do
  namespace :v1 do
    resources :users
  end
end

Place controllers in `app/controllers/api/v1/`.


LATAM-Image-V2.png

Hire Top LATAM Developers: Guide

We’ve prepared this guide that covers  benefits, costs, recruitment, and remote team management to a succesful hiring of developers in LATAM. 

Fill out the form to get our guide.

Gated content


Advanced Level (3+ Years)

1. How do you implement a GraphQL API in a Rails application?

Answer:

Use the graphql-ruby gem. Define types, queries, and mutations in app/graphql. Example:

class Types::QueryType < Types::BaseObject
  field :user, Types::UserType, null: true do
    argument :id, ID, required: true
  end
  def user(id:)
    User.find(id)
  end
end

Expose via a GraphqlController and route /graphql.

2. What are potential race conditions in uniqueness validations, and how do you mitigate them?

Answer:

Uniqueness validations can fail under concurrent writes. Mitigate with database constraints and error handling:

validates :email, uniqueness: true
add_index :users, :email, unique: true

Rescue ActiveRecord::RecordNotUnique for conflicts.

3. How would you design a multi-tenant architecture in Rails?

Answer:

Use schema-based separation (PostgreSQL schemas per tenant) or row-level tenancy (scoping by tenant_id). Use gems like Apartment for schemas or RequestStore for row-level scoping.

4. How can you prevent memory bloat in long-running Rails processes?

Answer:

Avoid large object retention, use object pools, offload tasks to jobs, use find_each for batch processing, and restart processes periodically (e.g., with Puma workers or memory_profiler).

5. How do the methods for eager loading and preloading associations differ in complex query optimization?

Answer:

includes chooses between preload (separate queries) or eager_load (JOIN) based on conditions. Example:

User.eager_load(:posts) # uses JOIN
User.preload(:posts)    # uses separate queries

eager_load may return duplicates without .distinct.

6. What is event sourcing, and how can it be implemented in a Rails app?

Answer:

Event sourcing stores state as events. Use rails_event_store. Example:

class OrderPlaced < RailsEventStore::Event; end
Rails.configuration.event_store.publish(OrderPlaced.new(data: { order_id: 1 }))

Replay events to rebuild state.

7. How does Rails handle database deadlocks, and what should your app do in response?

Answer:

Rails doesn’t retry deadlocks. Rescue ActiveRecord::Deadlocked with exponential backoff:

retries ||= 0
begin
  Order.transaction { ... }
rescue ActiveRecord::Deadlocked
  retries += 1
  sleep(0.1 * (2 ** retries))
  retry if retries < 3
end

8. What are the drawbacks of excessive use of callbacks in models, and how can you refactor them?

Answer:

They cause tight coupling and hidden behavior. Refactor to service objects, form objects, or explicit controller/job logic.

9. How would you implement custom ActiveRecord types?

Answer:

Create a subclass of ActiveRecord::Type::Value:

class MoneyType < ActiveRecord::Type::Value
  def cast(value)
    value.to_f
  end
end

class Product < ApplicationRecord
  attribute :price, MoneyType.new
end

10. How can you ensure background jobs are idempotent and safe to retry?

Answer:

Use unique job IDs, check state, and avoid non-atomic operations:

return if job_already_processed?(order_id)

Use transactions for side-effect-free operations.

11. What are database advisory locks and how can they be used in a Rails app?

Answer:

Advisory locks are application-level locks in PostgreSQL. Example:

ActiveRecord::Base.connection.execute("SELECT pg_advisory_lock(123)")

Use to prevent race conditions across processes.

12. What are some anti-patterns in ActiveRecord modeling, and how can they be avoided?

Answer:

Fat models, callback overuse, and scope reliance. Use service objects, decorators, and minimize model responsibilities.

13. How can you prevent query injection vulnerabilities in custom SQL?

Answer:

Use parameterized queries:

User.where("email = ?", params[:email])

Avoid raw input interpolation; use sanitize_sql for dynamic conditions.

14. What is a race condition in counter caching and how can it be resolved?

Answer:

Race conditions occur during concurrent counter updates. Use atomic updates:

Post.increment_counter(:comments_count, post.id)

Or database triggers for reliability.

15. What are database views and how can you integrate them with Rails models?

Answer:

Create a read-only model:

class Report < ApplicationRecord
  self.table_name = "user_reports"
  def readonly?
    true
  end
end

Views offload complex reporting to the DB.

16. How does Rails cache versioning work with ActiveRecord?

Answer:

Uses updated_at or cache_key_with_version:

Rails.cache.fetch(post.cache_key_with_version) { expensive_computation }

Invalidates stale data on record updates.

17. How would you profile a slow Rails endpoint in production?

Answer:

Use NewRelic, Skylight, or ActiveRecord::QueryLogs. Enable query logging:

config.active_record.query_log_tags_enabled = true

Combine with performance traces to find bottlenecks.

18. How do you implement database partitioning in a Rails app?

Answer:

Use PostgreSQL partitioning:

create_table :logs, partition_key: :created_at do |t|
  t.datetime :created_at
end

Route queries with custom logic or pg_party.

19. How can you persist and query JSON columns in PostgreSQL with Rails?

Answer:

Use jsonb for indexing:

User.where("preferences ->> 'language' = ?", "en")

jsonb supports efficient filtering.

20. What strategies would you use to reduce cold start time in large Rails apps?

Answer:

Minimize initializers, use lazy-loading, reduce gems, precompile assets, and use bootsnap. Limit frameworks in config/application.rb for API mode.

21. How can you safely apply concurrent database migrations in a production environment?

Answer:

Use non-locking operations, avoid change_column, and use reversible blocks. Use strong_migrations to catch unsafe migrations.

22. How does `ActiveJob` handle retry mechanisms and what are its limitations?

Answer:

Adapters (e.g., Sidekiq) define retries. Use retry_on, but complex logic requires adapter-specific settings for delays and dead-letter queues.

23. What are dry transactions, and how can you implement them in a Rails app?

Answer:

Dry transactions model business flows as composable steps using dry-transaction. Steps return Success() or Failure() objects.

24. What is a virtual attribute in Rails and how is it used?

Answer:

Virtual attributes are non-persisted fields:

attr_accessor :terms_accepted

Use with validations for form input without storage.

25. How would you implement row-level security (RLS) in a Rails app using PostgreSQL?

Answer:

Enable RLS:

ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;

Set session variables:

ActiveRecord::Base.connection.execute("SET SESSION current_tenant_id = 1")

Define policies in PostgreSQL for filtering.

26. How do pessimistic and optimistic locking differ in Rails?

Answer:

Optimistic locking uses lock_version to fail conflicting updates. Pessimistic locking locks rows:

Model.lock("FOR UPDATE").find(id)

Use pessimistic locking for frequent conflicts.

27. How can you ensure Rails caching remains valid across deployments?

Answer:

Use digest-based keys:

<% cache ["users", user.id, user.updated_at] do %>

Clear caches with rails dev:cache or tmp/restart.txt.

28. How can you add custom instrumentation to a Rails app for monitoring?

Answer:

Use ActiveSupport::Notifications:

ActiveSupport::Notifications.instrument("custom.event", payload: { user_id: 1 }) do
  # code to monitor
end

Subscribe for logging or metrics.

29. How do you manage long-running transactions in Rails, and what are the risks?

Answer:

Keep transactions short to avoid deadlocks. Exclude external calls or user input. Split logic to minimize lock duration.

30. How would you implement an audit trail in a Rails application?

Answer:

Use audited or paper_trail:

has_paper_trail

Or log changes in a custom model with user IDs and timestamps.

31. What are the implications of eager loading too many associations in Rails?

Answer:

Causes slow queries and high memory use. Use selective loading, preload, or pagination.

32. How can you implement a secure API-only Rails application?

Answer:

Use --api mode, JWT/OAuth, CORS, rate limiting (Rack::Attack), and minimal middleware.

33. How would you handle background jobs that depend on a specific sequence of events?

Answer:

Use job chaining or orchestration:

MyJob.perform_later.then(AnotherJob).then(FinalJob)

Or use the saga pattern for transactional logic.

34. How do Rails engines work and when would you use one?

Answer:

Engines are mini Rails apps for reusable components (e.g., admin panels).

35. What are “service layers” in Rails and why are they useful?

Answer:

Service layers are POROs for business logic:

UserSignupService.new(params).call

They improve testability and modularity.

36. How would you ensure atomic operations across multiple models?

Answer:

Use transactions:

ActiveRecord::Base.transaction do
  user.save!
  profile.save!
end

Use save! to rollback on failure.

37. How can you manage user authorization in a Rails app?

Answer:

Use Pundit or CanCanCan:

authorize @post

Scope queries and hide disallowed actions.

38. How does `rails db:structure:dump` differ from `db:schema:dump`?

Answer:

db:schema:dump creates a Ruby schema. db:structure:dump generates SQL (structure.sql) for advanced DB features.

39. What’s the role of middleware in Rails, and how can you add custom middleware?

Answer:

Middleware processes requests/responses. Add custom middleware:

config.middleware.use MyCustomMiddleware

Use for logging or authentication.

40. How would you implement full-text search in a Rails application?

Answer:

Use PostgreSQL tsvector, pg_search, or Elasticsearch based on scalability needs.

41. How does Rails handle concurrency, and what are potential pitfalls in threaded servers?

Answer:

Rails is thread-safe, but code/gems must be. Avoid class variables, use thread-local storage, and guard race conditions with mutexes or transactions.

42. How would you implement API rate limiting in a Rails app?

Answer:

Use rack-attack:

Rack::Attack.throttle("req/ip", limit: 60, period: 1.minute) do |req|
  req.ip
end

Use Redis for counters.

43. How do you handle global error reporting in a large Rails application?

Answer:

Use rescue_from, Sentry, or Rollbar. Avoid leaking sensitive data in logs.

44. What are decorators and how do they differ from presenters or helpers?

Answer:

Decorators (Draper) wrap models for presentation logic. Unlike helpers (global methods), they’re object-oriented. Presenters may coordinate multiple models.

45. How do you implement circuit breakers in a Rails app for external services?

Answer:

Use circuitbox:

Circuitbox.circuit(:external_service, open_after: 3, timeout: 5) do
  HTTP.get("https://api.example.com")
end

Fails over when open.

46. How would you implement database sharding in a Rails app?

Answer:

Use octopus or Rails 6+ multiple databases. Route to shards by user or tenant.

47. What are some considerations when building a Rails app with real-time features?

Answer:

Use Action Cable or Pusher. Configure Redis for pub/sub and scale with background jobs or external WebSocket servers.

48. How does Rails internally manage `has_many :through` associations and what are its performance trade-offs?

Answer:

Uses multiple joins via the join model. More flexible than has_and_belongs_to_many but requires indexed join tables for performance.

49. What’s the best way to structure a Rails monolith for long-term maintainability?

Answer:

Use domain-driven design, services, decorators, policies, and engines for isolation.

50. How can you use Common Table Expressions (CTEs) for query optimization in Rails?

Answer:

Use Arel for CTEs:

cte = Arel::Nodes::With.new(
  Arel::Nodes::As.new(
    Arel.sql("recent_users"),
    User.where("created_at > ?", 1.month.ago).arel
  )
)
User.find_by_sql(cte.to_sql + " SELECT * FROM recent_users")

CTEs simplify complex queries.