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๋ฒ์ ์ฟผ๋ฆฌ๋ก ์ค์ผ ์ ์์ต๋๋ค.
๐จ 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 ํธํ์ฑ, ๊ฐ๊ฒฉ ๊ตฌ์กฐ, ์ค์ผ์ผ๋ง ์ต์ ์ ๊ธฐ์ค์ผ๋ก ๋น๊ต.