Налаштування ActiveRecord для Ruby on Rails

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Налаштування ActiveRecord для Ruby on Rails
Середня
~1 робочий день
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Настройка ActiveRecord для Ruby on Rails

ActiveRecord — реалізація паттерну Active Record від DHH, вбудована в Rails. У Rails 7.x з'явилися async queries, encrypts, строгі моделі та інструмент компонування запитів через with. Розглядаємо актуальну настройку для Rails 7.1+.

Конфігурація database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  variables:
    statement_timeout: '10s'

development:
  <<: *default
  database: myapp_development

production:
  primary:
    <<: *default
    url: <%= ENV['DATABASE_URL'] %>
  replica:
    <<: *default
    url: <%= ENV['DATABASE_REPLICA_URL'] %>
    replica: true

Конфігурація реплики

# config/application.rb
config.active_record.database_selector = { delay: 2.seconds }
config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session

# app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  connects_to database: { writing: :primary, reading: :replica }
end

Модель

class Product < ApplicationRecord
  belongs_to :category
  has_many :product_tags, dependent: :destroy
  has_many :tags, through: :product_tags
  has_many :images, -> { order(:sort_order) }, class_name: 'ProductImage', dependent: :destroy

  enum :status, { draft: 'draft', published: 'published', archived: 'archived' }, prefix: true

  validates :title, presence: true, length: { maximum: 500 }
  validates :slug, presence: true, uniqueness: true

  before_validation :generate_slug, if: -> { slug.blank? && title.present? }

  scope :published,    -> { where(status: :published) }
  scope :in_category,  ->(id) { where(category_id: id) }
  scope :recent,       -> { order(created_at: :desc) }
  scope :with_preview, -> { includes(:category, :tags, images: []) }

  private
  def generate_slug
    self.slug = title.parameterize
  end
end

Міграція

class CreateProducts < ActiveRecord::Migration[7.1]
  def change
    create_table :products do |t|
      t.string  :title,       limit: 500, null: false
      t.string  :slug,        limit: 520, null: false
      t.decimal :price,       precision: 12, scale: 2
      t.string  :status,      limit: 20, null: false, default: 'draft'
      t.references :category, null: false, foreign_key: { on_delete: :restrict }
      t.jsonb   :meta
      t.timestamps
    end

    add_index :products, :slug, unique: true
    add_index :products, [:status, :created_at]
    add_index :products, [:category_id, :status]
  end
end

Запити

def index
  @products = Product
    .published
    .in_category(params[:category_id])
    .with_preview
    .recent
    .page(params[:page]).per(24)
end

Використовуємо Bullet gem у розробці для виявлення N+1:

# Gemfile
gem 'bullet', group: :development

# config/environments/development.rb
Bullet.enable = true
Bullet.rails_logger = true

Терміни

Настройка для нового Rails-проекту: 1 день. Оптимізація: 1–2 дні.