Model-View-Controller in Ruby on Rails

dou.eu 2 miesięcy temu

Ruby on Rails, is a powerful web application framework that embraces the Model-View-Controller (MVC) design pattern. If you're just starting your Rails journey, understanding MVC is crucial because it defines how your application is structured and how its components interact with one another.

In this post, we'll break down MVC using a simple project example: Store app with Product and Category models. This example demonstrates Rails' ability to handle data, views, and user interactions seamlessly.


What is MVC?

MVC stands for:

  • Model: Represents the data and the business logic of your application. In Rails, models handle database interactions.
  • View: Displays the data to the user. Views in Rails are typically written in HTML with embedded Ruby (ERB) or other templating engines.
  • Controller: Handles user input and updates the model or view accordingly. Controllers act as the middleman between models and views.

Rails automatically organizes these components into separate directories: app/models, app/views, and app/controllers.

MVC schema from the Ruby on Rails Guide

In the official Ruby on Rails Guide, you can find detailed explanations about all the aspects. Here, we will discuss a simpler example to familiarize ourselves with the MVC pattern.


Let's create a basic Rails app called Store:

$ rails new store

And see how each MVC component plays a role.

The Model

The model represents the application's data. In our Store app, we'll define two models: Product and Category.

Run these commands to generate the models:

$ rails generate model Category name:string description:text $ rails generate model Product name:string price:decimal category:references

Rails will create database migrations and model files for you. Note that rails generators use the parameters (name:string description:text) that create database columns with specific types. You can see and edit them in the migration files (read more about Active Record Migration files).

After generating the models, run the migrations to update the database:

$ rails db:migrate

Define associations between models:

# app/models/category.rb class Category < ApplicationRecord has_many :products end # app/models/product.rb class Product < ApplicationRecord belongs_to :category end

The Controller

The controller connects user input with the model and view. Let’s create a ProductsController and a CategoriesController to handle requests.

Generate the controllers:

$ rails generate controller Products $ rails generate controller Categories

Add basic actions for the ProductsController:

# app/controllers/products_controller.rb class ProductsController < ApplicationController def index @products = Product.all end def show @product = Product.find(params[:id]) end def new @product = Product.new end def create @product = Product.new(product_params) if @product.save redirect_to @product, notice: 'Product was successfully created.' else render :new end end private def product_params params.require(:product).permit(:name, :price, :category_id) end end

The View

The view displays data to the user. Rails’ convention automatically looks for view templates matching controller actions, such as index or show.

Create a file for the index action:

<!-- app/views/products/index.html.erb --> <h1>Products</h1> <ul> <% @products.each do |product| %> <li> <%= link_to product.name, product_path(product) %> — $<%= product.price %> </li> <% end %> </ul> <%= link_to 'Add a Product', new_product_path %>

And for the show action:

<!-- app/views/products/show.html.erb --> <h1><%= @product.name %></h1> <p>Price: $<%= @product.price %></p> <p>Category: <%= @product.category.name %></p> <%= link_to 'Back to Products', products_path %>

Note, that in this example we use instance variables in the views (they starts with @ sign).

Routes

Define routes for products and categories:

# config/routes.rb Rails.application.routes.draw do resources :products resources :categories end

How MVC Works Together

Here’s what happens when a user visits the /products page:

  1. Router: The request is routed to the ProductsController#index action.
  2. Controller: The index action fetches all products from the database and assigns them to @products.
  3. View: The corresponding index.html.erb file displays the list of products.
  4. Model: If data needs to be updated (e.g. during create or update action), the model handles database interactions.

Conclusion

Understanding MVC is the foundation of Rails development. By dividing your app into models, views, and controllers, Rails makes it easy to build and maintain web applications. As you grow, you’ll explore advanced features like validations, callbacks, and associations.

Start experimenting with your app and see how each component of MVC works to create a seamless experience for developers and users.


Stay tuned! In my upcoming posts, I want to explain how to quickly build CRUD Applications with generators and make the styling better with Tailwind CSS.


Idź do oryginalnego materiału