Rails patterns & best practices
Table of Contents
a summary of the courses rails 4 patterns and the older rails best practices (rails 3) by code school, as well as some additional material.
1 models
- only use callbacks for manipulating internal state, no tight coupling with other models
- set callbacks as
protected
- avoid "god objects": anti pattern because it violates Single Responsibility Principle
- not everything needs to be database backed -> encapsulate business logic out of DB backed models; also useful for proper REST architecture.
- keep serialization out of controllers by using
ActiveModel::Serializers
(pointGemfile
entry to GitHub repo) - use pluck method if you don't need AR objects (also see Getting to Know Pluck and Select by Gavin Miller)
ActiveSupport::Memoizable
was deprecated in Rails 3.1; use||=
or memoist- if you use them a lot, also index columns you order by
- if possible set default values in database, not in a filter
- use bullet gem to find N+1 queries and other performance issues
- use
size
with counter caches - do batch processing with find_each
- user delegate to avoid Law of Demeter violations
- use to_param for friendly URLs
2 controllers
- ask object to perform an action, don't query its internal state (business logic -> model)
- uses scopes in model instead of logic in controller (also see default_scope and unscoped)
- use merge method to merge scopes instead of duplicating conditions (last scope wins in case of shared column)
- filter sensitive parameters from logs by using
config.filter\_parameters
inconfig/application.rb
- good examples for filters: authorization, logging, wizards
- use presenters to avoid complex controller actions
- use the new responder syntax (
respond_to
class method +respond_with
)
3 views
- no queries in views!
- don't use instance variables in partials, use locals instead
- use nested layouts when all actions of a controller renders into a content_for
4 general
- avoid duplication by using concerns (see Put chubby models on a diet with concerns by dhh)
- use decorators for view-related business logic (
app/decorators
) - specify ruby version in Gemfile
- use foreman for Procfile-backed apps