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 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


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 subclasses Car and Truck.


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 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.

Last updated