Опишите архитектуру MVC в контексте Rails.ruby-40

MVC (Model-View-Controller) — это фундаментальная архитектурная парадигма, которую Rails реализует особенно элегантно. Рассмотрим каждый компонент и их взаимодействие в контексте Rails.

1. Model

Ответственность: Работа с данными и бизнес-логикой

Ключевые характеристики:

  • Наследуется от ActiveRecord::Base
  • Представляет таблицу в БД
  • Содержит валидации, ассоциации, колбэки
  • Инкапсулирует бизнес-логику

Пример модели:

class User < ApplicationRecord
  has_many :posts
  validates :email, presence: true, uniqueness: true

  before_create :generate_confirmation_token

  def active_posts
    posts.where(status: 'active')
  end

  private

  def generate_confirmation_token
    self.confirmation_token = SecureRandom.hex(10)
  end
end

Где располагается: app/models/

2. View

Ответственность: Отображение данных пользователю

Особенности в Rails:

  • По умолчанию используется ERB (Embedded Ruby)
  • Альтернативы: Haml, Slim
  • Частичные шаблоны (partials) для повторного использования
  • Layouts для общего оформления

Пример view (ERB):

<h1><%= @user.name %></h1>

<% if @user.posts.any? %>
  <ul>
    <% @user.posts.each do |post| %>
      <li><%= post.title %></li>
    <% end %>
  </ul>
<% else %>
  <p>No posts yet</p>
<% end %>

<%= render 'shared/footer' %>

Где располагается: app/views/контроллер/действие.html.erb

3. Controller

Ответственность: Обработка запросов, посредник между Model и View

Типичный flow:

  1. Получает параметры запроса
  2. Работает с моделью
  3. Подготавливает данные для view
  4. Определяет формат ответа

Пример контроллера:

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update]

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

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user, notice: 'User created!'
    else
      render :new
    end
  end

  private

  def set_user
    @user = User.find(params[:id])
  end

  def user_params
    params.require(:user).permit(:name, :email, :password)
  end
end

Где располагается: app/controllers/

Полный цикл запроса в Rails MVC

  1. Маршрутизация (config/routes.rb):

    resources :users
    

    Направляет /users/1 к UsersController#show

  2. Контроллер получает запрос, загружает данные:

    @user = User.find(params[:id])
    
  3. Представление рендерится с данными:

    <h1><%= @user.name %></h1>
    
  4. Ответ отправляется клиенту

Дополнительные компоненты в Rails

Helpers

module UsersHelper
  def display_user_avatar(user)
    if user.avatar.present?
      image_tag(user.avatar_url)
    else
      content_tag(:span, user.initials, class: 'avatar')
    end
  end
end

Mailers

class UserMailer < ApplicationMailer
  def welcome_email(user)
    @user = user
    mail(to: @user.email, subject: 'Welcome!')
  end
end

Jobs

class ProcessUserDataJob < ApplicationJob
  queue_as :default

  def perform(user)
    user.process_data!
  end
end

Отклонения от классического MVC

  1. ActiveJob: Для фоновых задач
  2. ActiveStorage: Для работы с файлами
  3. Channels: Для WebSocket (ActionCable)

Резюмируем: Rails реализует MVC-архитектуру с добавлением своих соглашений и дополнительных компонентов. Модели отвечают за данные, представления за отображение, контроллеры за логику запросов. Эта четкая сепарация ответственностей делает Rails-приложения структурированными и поддерживаемыми.