Topics
"Convention over Configuration" (CoC)
Rails offers several conventions and tools to organize and structure a codebase. Typically, they help to modularize and DRY up an application. Here are some popular ones:
1. Code Organization and Modularity
Concerns (see ours for Controller files)
Purpose: To organize and reuse code across models or controllers.
Example: Using
ActiveSupport::Concern
to extract shared logic from multiple models and put it into a module.Code Examples:
included do; before_action :authenticate_user!; end
Helpers
Purpose: Assist views by providing reusable methods to handle presentation logic.
Example: A
date_format
helper that takes a date and returns it in a specific string format.Code Examples:
def formatted_date(date); date.strftime('%B %d, %Y'); end
Service Objects
Purpose: Encapsulate business logic or actions into plain old Ruby objects, keeping controllers and models slim.
Example: A
UserRegistrationService
that handles the complexities of registering a user.
2. Data Management
Active Record
Purpose: ORM framework to represent and manipulate data in relational databases. Provides a way to create, read, update, and delete records without writing SQL statements.
Example:
User.find_by(email: 'example@email.com')
to fetch a user by their email address without writing a direct SQL query.Code Examples:
User.find_by(email: 'example@email.com')
Scopes
Purpose: Provide a way to define commonly-used ActiveRecord queries which can be referenced as method calls on the associated models.
Example:
published
scope on anArticle
model to fetch only published articles.Code Examples:
scope :published, -> { where(published: true) }
Callbacks
Purpose: Hook into the lifecycle of an Active Record object to execute logic at certain points.
Example: Sending a welcome email after a
User
is created.Code Examples:
before_save :normalize_name
,after_create :send_welcome_email
Validators
Purpose: Ensure data integrity by checking the validity of model attributes before saving to the database.
Example: Ensuring a
User
email is present and formatted correctly.Code Examples:
validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
Polymorphic Associations (has_many, belongs_to, etc.)
Purpose: Allow a model to belong to multiple other types of models on a single association.
Example: A
Comment
model that can belong to either anArticle
or aPhoto
.Code Examples:
has_many :posts
3. User Interface & Presentation
Partials
Purpose: DRY up views by extracting pieces of markup into reusable files.
Example: A
_header.html.erb
partial that's used across multiple views.Code Examples:
<%= render 'shared/footer' %>
View Components (or simply Components)
Purpose: Encapsulate parts of the view into reusable and testable units.
Example: A
NavbarComponent
that renders the navigation bar.
4. Jobs & Background Processing
Active Job
Purpose: Framework for declaring background jobs and making them run on various queuing backends.
Example: Sending bulk emails to users.
5. Mail & Communication
Action Mailer
Purpose: Framework for designing email services using templates.
Example: A
UserMailer
to send welcome emails and password resets.
6. Application Enhancements
Active Storage
Purpose: Attach files to ActiveRecord objects.
Example: Attaching an image to an
Article
object.Code Examples:
has_one_attached :profile_picture
Action Text
Purpose: Rich text content and editing, integrating with Active Storage for attachments.
Example: Adding a rich text editor to a blog platform for article creation.
Active Job
Purpose: Framework for declaring background jobs and making them run on a variety of queueing backends.
Example: Sending bulk emails in the background.
Code Examples:
class BulkEmailJob < ApplicationJob; queue_as :default; def perform(*args); # sending email logic here; end; end
7. Advanced Relations & Associations
Single Table Inheritance (STI)
Purpose: Inherit from a base model class, allowing multiple subclasses to have specific behaviors but are stored in a single database table.
Example: A
Vehicle
model with subclassesCar
andTruck
.
8. Routing & Controllers
Routes
Purpose: Define URLs for your application and how they map to controllers, actions, and views.
Example: Routing a GET request to
/users
to theindex
action of theUsersController
.Code Examples:
get 'users', to: 'users#index'
Controller Filters (before_action, after_action, around_action)
Purpose: Execute methods in a controller before, after, or around the entire action.
Example: Authenticating a user before granting them access to an action.
Code Examples:
before_action :authenticate_user!, only: [:edit, :update]
Each of these tools and conventions helps Rails developers structure their applications in a maintainable and organized way.
Last updated