TGViewer
Codica - корисне про IT Codica - корисне про IT @codica · 2.09K subscribers
Post #5120 166
Показуємо, як винести валідацію та бізнес-логіку з моделей у ізольовані Service Objects за 3 кроки:

1️⃣ Виносимо складну валідацію в Contract (dry-validation):


class UserRegistrationContract < Dry::Validation::Contract
params do
required(:email).filled(:string)
required(:age).filled(:integer)
end

rule(:email) do
unless /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i.match?(value)
key.failure("має бути коректним email-ом")
end
end

rule(:age) do
key.failure("реєстрація доступна лише з 18 років") if value < 18
end
end


2️⃣ Використовуємо dry-monads для чистого повернення результату (Success/Failure):


class RegisterUser
include Dry::Monads[:result]

def call(params)
# 1. Валідуємо параметри
contract_result = UserRegistrationContract.new.call(params)
return Failure(contract_result.errors.to_h) if contract_result.failure?

# 2. Створюємо користувача (бізнес-логіка)
user = User.create!(contract_result.to_h)
Success(user)
rescue ActiveRecord::RecordNotUnique
Failure(email: ["цей email вже зайнятий"])
end
end


3️⃣ Тонкий і чистий контролер:


class UsersController < ApplicationController
def create
case RegisterUser.new.call(user_params)
in Dry::Monads::Success(user)
render json: user, status: :created
in Dry::Monads::Failure(errors)
render json: { errors: errors }, status: :unprocessable_entity
end
end
end


🔥 Чому це оцінять на співбесіді та в коді:
• Single Responsibility: Модель відповідає ТІЛЬКИ за роботу з БД, Контракт — за валідацію, Сервіс — за бізнес-логіку.
• Відсутність "брудних" exceptions: Замість raise/rescue ми контрольовано повертаємо Success або Failure (Railway Oriented Programming).
• Тестувати такі контракти та сервіси в RSpec — суцільне задоволення, бо вони не потребують підйому бази даних.

А як ви виносити складну логіку з моделей у своїх проектах: використовуєте dry-rb, ActiveInteraction чи старі добрі PORO-сервіси? 👇

TikTok | Instagram | Telegram
  • 🔥 3
More from @codica
  1. Oct 9, 2026🐞 5 шпаргалок для QA, які бережуть нерви перед релізом Коли реліз уже близько, останнє, ч…
  2. Oct 9, 2026📚 Народ, ми тут дещо затіяли. Запускаємо серію IT-шпаргалок на всі випадки життя — від «я…
  3. Oct 9, 2026Тож перша десятка вже тут 📚 Зберігайте, пересилайте друзям і… поїхали читати 🚀 🛒 — поси…
  4. Oct 9, 2026🤖 40 КНИГ, ЩОБ РОЗІБРАТИСЯ В AI — ВІД НУЛЯ ДО AGI Друзі, знайшли для вас аж 40 книг про A…
  5. Oct 8, 2026Post #5192
  6. Oct 8, 2026#codica_js
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →