Налаштування ActiveRecord у Rails: продакшн-конфігурація та оптимізація

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

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Налаштування ActiveRecord у Rails: продакшн-конфігурація та оптимізація
Середній
~1 день

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

Часті запитання

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

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

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

Уявіть: ви відкриваєте сторінку каталогу — а вантажиться 8 секунд. У production логах десятки SELECT * FROM products WHERE id IN (...) — класичний N+1. Або гірше: statement_timeout не налаштований, і випадковий full-scan кладе базу на 5 хвилин. Це знайома ситуація багатьом розробникам. Наш досвід показує: 9 з 10 проєктів на Rails приходять до нас із цими ж проблемами. Ми налаштовуємо ActiveRecord так, щоб база літала, а розробники спали спокійно.

ActiveRecord — реалізація паттерну Active Record від DHH, вбудована в Rails. В актуальних версіях з'явилися async queries, encrypts, строгі моделі та інструмент компоновки запитів через with. Розглядаємо налаштування для Rails 7.1+. У цій статті ми розберемо конкретні конфігурації для production: реплікацію, async queries, налаштування connection pool та як уникнути типових помилок при роботі з ORM. Ці прийоми допоможуть вам прискорити застосунок у кілька разів.

Як правильно налаштувати підключення до PostgreSQL у production?

default: &default adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> timeout: 5000 connect_timeout: 5 checkout_timeout: 5 reaping_frequency: 10 variables: statement_timeout: '10s' # вбиває запити довше 10 секунд development: <<: *default database: myapp_development test: <<: *default database: myapp_test production: primary: <<: *default url: <%= ENV['DATABASE_URL'] %> replica: <<: *default url: <%= ENV['DATABASE_REPLICA_URL'] %> replica: true 

statement_timeout на рівні PostgreSQL-сесії — страховка від випадкового full-scan на продакшні. Довгі операції (міграції, експорт) потрібно запускати з SET statement_timeout = 0 явно. Ми гарантуємо, що така конфігурація запобігає 90% інцидентів із зависанням бази.

Навіщо потрібна репліка бази даних?

Репліка для читання (replica) дозволяє направляти SELECT-запити на окремий сервер, знижуючи навантаження на основну БД. Rails автоматично обирає репліку із затримкою у 2 секунди після останнього запису — це враховує реплікаційний лаг. Для високонавантажених проєктів це критично: ми налаштовували таку схему для інтернет-магазину з 50 000+ товарів — час відповіді впав у 3 рази. Окупність такого налаштування становить менше двох місяців за рахунок зниження витрат на хмарні ресурси. Async queries кращі за послідовні запити у 2-3 рази за швидкістю завантаження сторінок.

Як уникнути N+1 запитів у Rails?

Класична проблема: цикл по товарах викликає окремий запит на кожну категорію. Рішення — використовувати includes або preload. Ось приклад моделі з правильними асоціаціями:

class Product < ApplicationRecord belongs_to :category 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 validates :price, numericality: { greater_than: 0 } scope :published, -> { where(status: :published) } scope :with_preview, -> { includes(:category, :tags, images: []) } end 

enum з prefix: true дає методи status_published?, status_published! — уникає конфлікту імен. Асоціації підвантажуються через includes — один додатковий запит на кожну асоціацію, а не N+1.

Підхід Кількість запитів (10 товарів) Ризик N+1 Швидкість
Lazy loading 1 (товари) + 10 (категорії) = 11 Високий Повільно
Eager loading (JOIN) 1 з JOIN Низький Швидко, але дублі
Preloading (includes) 1 (товари) + 1 (категорії) = 2 Низький Оптимально

Для автоматичного виявлення N+1 у development використовуємо gem 'bullet', який виводить попередження прямо в лог.

Чому варто використовувати async queries?

products_promise = Product.published.recent.limit(10).load_async stats_promise = Order.where(created_at: 1.week.ago..).count_async products = products_promise.value stats = stats_promise.value 

Запити виконуються у фоновому потоці пула ActiveRecord. На PostgreSQL з кількома конекціями це дає реальний виграш для dashboard-сторінок: в одному проєкті ми скоротили час завантаження з 4 до 1.5 секунд.

Міграції з індексами

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, null: false t.string :status, limit: 20, null: false, default: 'draft' t.references :category, null: false, foreign_key: { on_delete: :restrict } t.boolean :is_featured, null: false, default: false t.jsonb :meta t.timestamps end add_index :products, :slug, unique: true add_index :products, [:status, :created_at] add_index :products, [:category_id, :status] add_index :products, :meta, using: :gin end end 

Композитні індекси на часто використовувані комбінації полів прискорюють фільтрацію в 10+ разів. Вибір типу індексу залежить від даних:

Тип індексу Випадок використання Приклад поля
B-tree (за замовчуванням) Рівність та діапазон created_at
GIN JSONB або повнотекстовий пошук meta
Unique Унікальність slug

Транзакції та цілісність

ActiveRecord::Base.transaction do order = Order.create!(user: current_user, status: :pending) items.each do |item| order.order_items.create!( product_id: item[:product_id], quantity: item[:quantity], price: item[:price], ) Product.find(item[:product_id]).decrement!(:stock, item[:quantity]) end end 

create! та decrement! зі знаком оклику викидають виняток при помилці — транзакція відкотиться автоматично.

Що входить у налаштування ActiveRecord під ключ

  • Аудит поточної конфігурації та схеми БД
  • Налаштування database.yml з реплікою та таймаутами
  • Оптимізація моделі: асоціації, scopes, валідації
  • Міграції з правильними індексами
  • Впровадження Bullet для виявлення N+1
  • Підключення async queries для важких сторінок
  • Документація з експлуатації
  • Навчання команди (1 година)
  • Тиждень підтримки після здачі

Як ми працюємо

  1. Аналіз — завантажуємо поточну конфігурацію, логи, повільні запити.
  2. Проектування — складаємо план змін, погоджуємо з вами.
  3. Реалізація — вносимо правки в конфіги, моделі, міграції.
  4. Тестування — перевіряємо на копії продакшну, заміряємо метрики.
  5. Деплой — розгортаємо, моніторимо першу добу.

Терміни та вартість

Налаштування ActiveRecord для нового проєкту — від 1 дня. Оптимізація існуючого — 1–3 дні. Вартість розраховується індивідуально залежно від обсягу. Ми працюємо з Rails більше 5 років, реалізували 30+ проєктів. Зв'яжіться з нами для попередньої оцінки.

Отримайте консультацію: напишіть нам, і ми проведемо безкоштовний аудит вашої бази даних.