NEGABARO Rails
Rails 개발에 필요한 핵심 개념들을 정리한 백과사전입니다.
🧱 Foundation
MVC 패턴
Model-View-Controller — Rails의 핵심 아키텍처
Model(데이터/비즈니스 로직), View(화면 표시), Controller(요청 처리/중개)로 애플리케이션을 분리하는 설계 패턴. Rails의 모든 것은 MVC를 기반으로 동작합니다.
Convention over Configuration
Rails의 핵심 철학 — 규약이 설정보다 우선
명시적인 설정 파일 대신 이름 규약(naming convention)을 따르면, Rails가 자동으로 연결해주는 철학. 예: Post 모델 → posts 테이블 → PostsController → app/views/posts/
Rails 디렉토리 구조
프로젝트 폴더별 역할과 컨벤션
Rails 프로젝트의 디렉토리 구조는 MVC 패턴을 물리적으로 반영합니다. app/, config/, db/, test/ 등 각 폴더의 역할이 명확히 정해져 있습니다.
Rack & Middleware
Rails 아래에서 동작하는 HTTP 처리 레이어
Rack은 Ruby 웹 서버와 프레임워크 사이의 인터페이스 규약입니다. Middleware는 요청/응답을 가로채어 처리하는 중간 레이어로, 양파껍질처럼 겹겹이 쌓입니다.
🚦 Routing & Controllers
RESTful Routes
resources 한 줄로 7개 라우트 자동 생성
REST(Representational State Transfer) 원칙에 따라 리소스 단위로 URL을 설계합니다. resources :posts 한 줄로 index, show, new, create, edit, update, destroy 7개 라우트가 생성됩니다.
Params & Strong Parameters
요청 파라미터 접근과 허용 목록 관리
params 해시로 URL 파라미터, 폼 데이터, JSON 바디에 접근합니다. Strong Parameters(require/permit)로 허용된 필드만 화이트리스트 방식으로 통과시켜 Mass Assignment 공격을 방지합니다.
Before Action & Callbacks
액션 실행 전후에 공통 로직을 끼워넣는 방법
before_action, after_action, around_action으로 Controller 액션 실행 전후에 공통 로직(인증 확인, 데이터 로딩 등)을 선언적으로 삽입합니다.
Controller Concerns
여러 Controller에서 공유하는 모듈
app/controllers/concerns/ 폴더에 모듈을 만들어 여러 Controller에서 include하여 코드를 재사용합니다. 인증, 페이지네이션, 검색 등 공통 기능에 활용.
🗄️ Models & Database
ActiveRecord
ORM — 객체로 데이터베이스를 조작
Object-Relational Mapping. Ruby 객체와 DB 테이블을 자동 매핑하여, SQL을 직접 작성하지 않고 Ruby 메서드로 데이터를 CRUD합니다.
Migrations (마이그레이션)
코드로 데이터베이스 스키마를 버전 관리
Ruby 코드로 DB 테이블 생성/수정/삭제를 정의하고, 시간순으로 실행하여 스키마를 버전 관리합니다. Git처럼 DB 변경 이력을 추적하고 롤백할 수 있습니다.
Associations (관계)
has_many, belongs_to — 모델 간 관계 설정
belongs_to, has_many, has_one, has_many :through 등으로 모델 간 관계를 선언적으로 정의합니다. 외래키 규약을 따르면 자동으로 연결됩니다.
Validations (유효성 검사)
Model 레벨에서 데이터 무결성 보장
validates 매크로로 모델에 유효성 검사를 선언합니다. presence, uniqueness, length, format 등 다양한 검증을 DB 저장 전에 수행합니다.
Model Callbacks
저장/삭제 전후에 자동 실행되는 훅
before_save, after_create, before_destroy 등 모델 라이프사이클 이벤트에 훅을 걸어, 특정 시점에 자동으로 로직을 실행합니다.
Scopes & Query Interface
재사용 가능한 쿼리를 이름 붙여 관리
scope 매크로로 자주 쓰는 쿼리 조건에 이름을 붙여 재사용합니다. 체이닝이 가능하여 복잡한 쿼리도 가독성 있게 작성할 수 있습니다.
N+1 쿼리 문제
성능의 적 — includes로 해결하는 방법
연관 데이터를 반복문에서 개별 조회하면 1(목록) + N(각 항목의 연관) 번 쿼리가 발생합니다. includes/preload/eager_load로 2번의 쿼리로 줄일 수 있습니다.
jsonb와 store_accessor
PostgreSQL의 jsonb 컬럼을 모델 속성처럼 다루기
jsonb는 JSON을 바이너리로 저장하는 PostgreSQL 컬럼 타입. store_accessor를 쓰면 jsonb 컬럼 하나에 여러 값을 넣고 일반 컬럼처럼 읽고 쓴다.
find_or_initialize_by vs create_or_find_by
RecordNotUnique가 터지는 이유 — 찾기와 만들기의 순서
두 메서드는 찾기와 만들기의 순서가 반대다. find_or_initialize_by는 SELECT 먼저, create_or_find_by는 INSERT 먼저. 동시 요청에서 RecordNotUnique가 난다면 후자로 바꿀 때다.
🎨 Views & Frontend
ERB & Partials
HTML 안에 Ruby를 삽입하고, 재사용 가능한 조각으로 분리
ERB(Embedded Ruby)는 HTML 안에 Ruby 코드를 삽입하는 템플릿 엔진입니다. Partial은 재사용 가능한 뷰 조각으로, 반복을 줄이고 코드를 정리합니다.
Layouts & yield
페이지의 공통 골격을 레이아웃으로 관리
application.html.erb 레이아웃에 공통 HTML 구조(head, nav, footer)를 정의하고, yield로 각 페이지의 고유 내용을 삽입합니다.
Form Helpers
form_with로 안전하고 편리한 폼 작성
form_with 헬퍼로 CSRF 토큰, HTTP 메서드, 파라미터 네이밍을 자동 처리합니다. 모델 객체를 전달하면 create/update URL도 자동 결정.
Turbo & Hotwire
JavaScript 없이 SPA 같은 UX 구현
Hotwire(HTML Over The Wire)는 서버에서 HTML을 보내고 Turbo가 페이지를 부분 업데이트하는 방식입니다. JavaScript를 최소화하면서 SPA 수준의 UX를 제공.
Stimulus
HTML 중심의 경량 JavaScript 프레임워크
HTML에 data-controller, data-action, data-target 속성을 추가하여 JavaScript 동작을 연결합니다. HTML이 주도하고, JS는 "양념" 역할.
🔐 Authentication & Security
Devise
Rails 표준 인증 시스템
회원가입, 로그인, 로그아웃, 비밀번호 재설정, 이메일 인증, OAuth 등을 제공하는 인증 gem. current_user, authenticate_user! 등 헬퍼를 자동 생성.
CSRF 보호
Cross-Site Request Forgery 공격 자동 방어
Rails는 모든 non-GET 요청에 CSRF 토큰을 자동으로 삽입/검증하여 위조 요청을 방지합니다. protect_from_forgery가 기본 활성화.
Strong Parameters
Mass Assignment 공격 방지
Controller에서 params.require(:model).permit(:field1, :field2)로 허용할 필드를 명시적으로 선언합니다. 허용되지 않은 필드는 자동 무시.
테넌트 분리 쿼리 패턴 — Model.where 대신 organization 스코프로 시작하기
마루티테넌트 Rails 앱에서 데이터 유출을 구조적으로 차단하는 쿼리 작성법
마루티테넌트 앱에서 Contract::Asset.joins(:contract).where(contracts: { organization_id: ... }) 같은 그로벌 쿼리는 ID 하나 잘못 넘기면 다른 조직의 데이터가 튀어나온다. organization.contracts에서 시작하면 쿼리 구조 자체가 테넌트 분리를 보장한다.
🧪 Testing
RSpec
BDD(Behavior-Driven Development) 테스트 프레임워크
describe/context/it 블록으로 테스트를 자연어처럼 작성합니다. expect(실제값).to eq(기대값) 문법으로 검증하며, Rails의 모든 계층을 테스트합니다.
FactoryBot
테스트 데이터를 깔끔하게 생성
Fixture 대신 Factory 패턴으로 테스트 데이터를 동적으로 생성합니다. create(:user), build(:post) 등 간결한 문법으로 필요한 데이터를 즉석에서 만듭니다.
Request Specs
HTTP 요청/응답을 테스트하는 통합 테스트
get, post, patch, delete 메서드로 실제 HTTP 요청을 시뮬레이션하고, 응답 상태 코드, 리다이렉트, 렌더링된 내용을 검증합니다.
🚀 Advanced
Background Jobs
Active Job + Sidekiq — 무거운 작업을 비동기로 처리
이메일 발송, 파일 처리, 외부 API 호출 등 시간이 걸리는 작업을 백그라운드 큐에 넣어 비동기로 처리합니다. 사용자는 즉시 응답을 받습니다.
Sidekiq: 릴리스와 비동기 잡의 함정
SIGTERM/SIGKILL — 긴 Sidekiq 잡이 배포 때마다 죽는 이유
비동기 잡이 배포 타이밍에 따라 통째로 사라지거나 status가 영원히 \"실행중\" 으로 고착될 수 있다. SIGTERM(우아한 종료)과 SIGKILL(강제 종료)의 차이, Sidekiq의 graceful shutdown 동작, OSS의 한계를 이해하면 왜 이런 사고가 나는지 보인다.
Action Cable
Rails 내장 WebSocket — 실시간 기능 구현
Rails에 내장된 WebSocket 프레임워크로, 서버에서 클라이언트로 실시간 데이터를 푸시합니다. 채팅, 알림, 실시간 업데이트에 활용.
Caching (캐싱)
반복 연산을 줄여 응답 속도를 극적으로 향상
Fragment Caching, Russian Doll Caching, Low-Level Caching 등으로 DB 쿼리와 뷰 렌더링 결과를 캐시하여 응답 속도를 수십 배 향상시킵니다.
Asset Pipeline & Vite
JavaScript, CSS, 이미지 등 프론트엔드 에셋 관리
Sprockets(전통), Webpacker(폐지), Vite(최신)로 JavaScript/CSS/이미지를 번들링하고, 핑거프린팅으로 캐시 최적화합니다.
Kamal 배포
Rails 공식 배포 도구 — Docker 기반 제로 다운타임 배포
DHH가 만든 Rails 공식 배포 도구. Docker 컨테이너로 어떤 VPS에든 배포 가능. DigitalOcean 등 소규모 서버에서는 로컬 빌드 후 레지스트리에 push하는 방식을 권장합니다.
background-removal-js — 브라우저에서 AI로 배경을 제거하는 원리
IS-Net 모델 + ONNX Runtime Web + WebGPU, 서버 없이 클라이언트에서 세그멘테이션
imgly/background-removal-js는 브라우저에서 서버 없이 AI로 이미지 배경을 제거한다. IS-Net(U-Net 계열) 모델을 ONNX Runtime Web으로 실행하며, WebGPU 가속도 지원한다. 이미지를 1024×1024로 리사이즈 → 모델이 알파마스크 출력 → 원본에 적용하는 구조.
📐 My Convention
Helper를 쓰지 않는 이유
My Convention — 데이터 로직은 Controller에, Helper는 최소한으로
Rails Helper는 편리하지만, 남용하면 전역 오염·테스트 어려움·책임 모호 등 구조적 문제를 만듭니다. 데이터 가공은 Controller, 표시 전용만 Helper.
DHH의 Rails 코딩 스타일
바닐라 Rails로 충분하다 — 37시그널스의 철학
Rails 창시자 DHH가 실천하는 코딩 원칙. 외부 라이브러리 최소화, 모든 것을 CRUD로 매핑, 상태를 불리언이 아닌 레코드로 관리하는 실전 철학.
📖 Rails Open Source 코드 읽기
Campfire (37signals)
DHH 스타일의 교과서 — Rails 기본 기능만으로 만든 실시간 채팅 앱
37시그널스가 ONCE 브랜드로 출시한 실시간 채팅 앱. Devise 없이 has_secure_password, Redis 없이 Solid 시리즈, 커스텀 액션 없이 CRUD만으로 구현된 DHH 스타일의 교과서.
Writebook (37signals)
ONCE 브랜드의 출판 도구 — delegated_type과 편집 이력 관리의 교과서
37시그널스의 ONCE 브랜드 출판 앱. delegated_type으로 다형성 콘텐츠(Page/Section/Picture)를 관리하고, Edit 레코드로 편집 이력을 추적합니다. Campfire와 같은 인증 패턴이지만, 접근 제어(Access)와 출판(Publication) 같은 독자적 패턴도 볼 수 있습니다.
Solid Queue (Rails)
Redis 없이 DB만으로 — Rails 8 기본 백그라운드 잡 시스템
Rails 8의 기본 ActiveJob 백엔드. Redis/Sidekiq 대신 데이터베이스(PostgreSQL/MySQL/SQLite)만으로 백그라운드 잡을 처리합니다. FOR UPDATE SKIP LOCKED으로 비차단 폴링 구현.
Solid Cache (Rails)
Redis 대신 SSD — 데이터베이스 기반 Rails 캐시 스토어
Rails 8의 기본 캐시 스토어. Redis/Memcached 대신 데이터베이스(SSD)를 활용하여 훨씬 큰 캐시를 유지할 수 있습니다. 쓰기 기반 확률적 만료와 Maglev 일관 해싱으로 샤딩 지원.
🏗 Infra
Rails 8 + SQLite — 프로덕션에서 써도 되는 이유
PostgreSQL 없이도 되는 시대가 왔다 — 37signals가 증명한 SQLite 프로덕션 운영
Rails 8은 SQLite를 프로덕션 데이터베이스로 공식 지원한다. Solid Queue(백그라운드 잡), Solid Cache(캐시), Solid Cable(웹소켓)까지 전부 SQLite로 동작. 37signals(Basecamp)가 실제 프로덕션에서 검증했다.
SQLite WAL 모드 — 장점과 단점
Write-Ahead Logging이 SQLite의 동시성 문제를 어떻게 해결하는가
WAL(Write-Ahead Logging)은 SQLite의 기본 DELETE 저널 모드를 대체하여 reader와 writer의 동시 접근을 가능하게 하는 모드다. Rails 8에서 기본 활성화되며, Solid Queue 같은 빈번한 소규모 트랜잭션 환경에서 특히 효과적이다.
초기 Rails 앱 디플로이 SaaS 비교
Fly.io, Render, DigitalOcean, Fargate, Railway, Heroku 등 실전 비교
Rails 초기 프로젝트를 디플로이할 때 어떤 PaaS/SaaS를 선택할지에 대한 실전 가이드. 무료 티어, Docker 지원, PostgreSQL/SQLite 호환성, 가격 구조, 스케일링 옵션을 기준으로 비교.