WebDevChallenges Logo
WebDevChallenges

My Rails Active Record Cheatsheet

Updated June 12, 21
I don't have years and years of experience with Rails so whenever I create a new Project, I need to open up old ones to see how I did things back then, this post is my new reference

Model Relations

One to one

# Account, foreign key is on this model's table
belongs_to :user
# User
has_one :category

One to many

# Category
has_many :user
# User, foreign key is on this model's table
belongs_to :category

Many to many

# Category
has_many :user_categories
has_many :users, through: :user_categories
# User
has_many :user_categories
has_many :categories, through: :user_categories
# UserCategory, this model holds all the foreign keys
belongs_to :user
belongs_to :category

Many to many with same model

# Report
belongs_to :issuer, class_name: 'User'
belongs_to :suspect, class_name: 'User'
# User
has_many :issued_reports, class_name: 'Report', foreign_key: :issuer_id
has_many :reports, class_name: 'Report', foreign_key: :suspect_id

Model Enums

enum status: { open: 1, closed: 2 }

Validations

validates :name, presence: true
validates :name, length: { maximum: 100 }
validates :description, length: { maximum: 500 }, presence: true
validates :slug, presence: true, if: :published?
validates :username, uniqueness: { case_sensitive: false }, allow_nil: true, allow_blank: true
validates :status, presence: true

Scopes

scope :is_favorite_of, -> (user) {
  joins('INNER JOIN "favorites" ON "favorites"."user_id" = "users"."id"')
    .where(favorites: { company_id: user })
}
scope :latest_favorites_first, -> {
  joins('INNER JOIN "favorites" ON "favorites"."user_id" = "users"."id"')
    .order("favorites.created_at DESC")
}
scope :with_category, -> (category) { joins(:user_categories).where(user_categories: { category_id: category }) }
scope :with_tag_partial, ->(tag_partial) { joins(:tags).where('lower(tags.name) LIKE ?', "%#{tag_partial.downcase}%").group('users.id') }
scope :age_from, ->(age_from) { where("date_of_birth < ?", (Date.today - age_from.years)) }
scope :age_to, ->(age_to) { where("date_of_birth > ?", (Date.today - age_to.years)) }

Migrations

Enum

add_column :users, :status, :integer, default: 1

Jointable

create_table :user_categories do |t|
  t.references :user, null: false, foreign_key: true
  t.references :category, null: false, foreign_key: true

  t.timestamps
end

Jointable for same model

create_table :reports do |t|
  t.references :issuer, null: false, foreign_key: { to_table: 'users' }
  t.references :suspect, null: false, foreign_key: { to_table: 'users' }

  t.timestamps
end