What is the MVC architecture in Ruby on Rails, and how does it work?

Updated Feb 20, 2026

Short answer

MVC is the architectural pattern that separates a Rails application into three responsibilities: models handle data, views handle presentation, and controllers handle requests and coordination. Rails uses this separation to make applications easier to organize, test, and maintain.

Deep explanation

Ruby on Rails is built around the Model-View-Controller (MVC) pattern, where each layer has a clear job. Instead of putting database logic, user interface code, and request handling into one place, Rails divides responsibilities so developers can change one part without unnecessarily affecting the others.

The key idea: controllers connect the user's request to the right data and presentation layer.

The three parts of MVC

ComponentResponsibilityCommon Rails location
ModelRepresents data, business rules, and database interactionsapp/models
ViewGenerates what the user sees, usually HTMLapp/views
ControllerReceives requests, calls models, and selects viewsapp/controllers

Model: A model represents application data and behavior. In Rails, models usually inherit from ApplicationRecord and use Active Record to communicate with the database. A model can contain validations, relationships, and business logic.

View: A view is responsible for presentation. Rails commonly uses ERB templates, which combine HTML with Ruby expressions. Views should focus on displaying information rather than deciding business rules.

Controller: A controller acts as the coordinator. It receives an HTTP request, performs actions using models, and passes data to views. Controllers should generally avoid containing large amounts of business logic.

A Rails request typically flows: browser → route → controller → model → view → response.

The request lifecycle can be visualized like this:

Rendering diagram…

How Rails uses MVC in practice

A typical Rails application maps MVC responsibilities through conventions:

  • A URL is matched by a route in config/routes.rb.
  • The route calls a controller action.
  • The controller interacts with models.
  • The controller provides data to a view.
  • The view generates the final response.

For example, a controller action might look like:

app/controllers/posts_controller.rb
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
end
end

The matching view can then access the controller's instance variable:

app/views/posts/show.html.erb
<h1><%= @post.title %></h1>
<p><%= @post.body %></p>

Rails does not require developers to manually connect every layer. Its convention-over-configuration philosophy automatically finds expected files and reduces setup work.

Why MVC is useful

MVC provides several benefits:

  • Maintainability: Developers know where different types of code belong.
  • Testing: Models, controllers, and views can be tested separately.
  • Collaboration: Multiple developers can work on different layers with fewer conflicts.
  • Flexibility: The same model can support multiple views, such as a web page and an API response.

However, MVC is not a guarantee of good design. A poorly structured Rails application can still become difficult to maintain if controllers become too large or models contain unrelated responsibilities.

MVC is a separation of responsibilities, not just a folder structure.

A common Rails principle is: keep controllers thin, keep views simple, and put domain behavior where it belongs.

Real-world example

Imagine building a blog application. A user visits /posts/5 to read a post. The router sends the request to PostsController#show, the controller asks the Post model for the record, and the view displays the title and content.

app/controllers/posts_controller.rb
def show
@post = Post.find(params[:id])
end

The model handles data rules, such as validating that a post has a title, while the view only decides how that information appears.

app/models/post.rb
class Post < ApplicationRecord
validates :title, presence: true
end

This separation means a developer can redesign the page without rewriting database logic, or change the data rules without modifying HTML templates.

Common mistakes

  • * **Fat controllers** - Putting business rules inside controllers makes code hard to test and reuse. Move domain logic into models or dedicated service objects when appropriate.
  • * **Complex views** - Adding calculations and decisions directly in templates creates messy presentation code. Keep views focused on rendering.
  • * **Confusing MVC with folders** - MVC is about responsibilities, not just placing files in `app/models`, `app/views`, and `app/controllers`.
  • * **Overloading models** - Putting every piece of application behavior into one model creates difficult-to-maintain classes. Split responsibilities when models become too large.

Follow-up questions

  • Why are Rails controllers usually kept “thin”?
  • What is the role of Active Record in Rails MVC?
  • Can a Rails application use MVC with an API instead of HTML pages?
  • What happens if MVC responsibilities are mixed together?

More Ruby on Rails interview questions

View all →