Topics
"Convention over Configuration" (CoC)
Last updated
"Convention over Configuration" (CoC)
Last updated
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:
Concerns
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.
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 an Article
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 an Article
or a Photo
.
Code Examples: has_many :posts
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.
Active Job
Purpose: Framework for declaring background jobs and making them run on various queuing backends.
Example: Sending bulk emails to users.
Action Mailer
Purpose: Framework for designing email services using templates.
Example: A UserMailer
to send welcome emails and password resets.
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
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 subclasses Car
and Truck
.
Routes
Purpose: Define URLs for your application and how they map to controllers, actions, and views.
Example: Routing a GET request to /users
to the index
action of the UsersController
.
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.