Hotwire Native + Rails 8 삽질 7가지 — 실기기에서만 터지는 버그들

Rails 8 + Hotwire Native으로 만든 모바일 앱의 대시보드 페이지를 Render에 배포한 뒤 실기기에서 점검하면서 만난 삽질 7가지를 정리했다. WKWebView 위에서 돌아가는 하이브리드 앱 특성상, 데스크톱 브라우저에서는 발견되지 않는 함정들이 많았다. 이 글에서 다루는 주요 키워드: Hotwire Native 모바일 레이아웃, Content Security Policy CDN 차단, Turbo const/let 재선언 에러, backdrop-filter 성능, Stimulus 컨트롤러 자동 등록, CSS contain 최적화. 프로젝트 환경 Backend: Rails 8 + PostgreSQL Frontend: Hotwire (Turbo + Stimulus) + ERB + Tailwind CSS 4 Mobile: Hotwire Native (iOS WKWebView) Realtime: ActionCable (WebSocket) Deploy: Render.com Asset Pipeline: importmap-rails (CDN pin 방식) 대시보드 페이지 구성: 코트 카드 grid (코트 수 x 라운드 수), 선수 DnD 리스트, 경기 목록, 교류 현황 통계. 코트 5개 x 8라운드 = 40장의 카드가 한 페이지에 렌더링되는 구조. ...

2026-03-21 · 8분 소요 · Seunghan

Rails 8 Hotwire 실전 삽질기 — DnD 배정, N+1 자동 감지, 테마별 Favicon

Rails 8 + Hotwire로 실시간 토너먼트 대시보드를 만들면서 하루 동안 겪은 3가지 삽질과 해결 과정. 이 문제들은 엣지 케이스가 아니라, Hotwire 프로그래밍 모델이 런타임에서 드러내는 자연스러운 마찰 지점들이다. 1. Turbo Stream + Stimulus DnD: DOM 교체 후 이벤트가 사라진다 문제 선수 칩을 코트 카드에 드래그하면 서버에 POST → Turbo Stream으로 코트 카드와 선수 목록을 교체하는 구조를 만들었다. 첫 번째 드래그는 잘 된다. 두 번째부터 아무 반응이 없다. 이벤트도, 요청도, 응답도 없다. ...

2026-03-21 · 9분 소요 · Seunghan
Rails Turbo Stream Bracket BYE Slot Debugging

Turbo Stream 누락 + BYE 슬롯 재활용 안 되는 버그 — Rails 8 대진표 디버깅 기록

대진표 관리 앱에서 두 가지 버그가 동시에 나왔다. 선수 추가 폼이 작동하지 않는 것처럼 보임 — 추가 버튼을 눌러도 목록이 갱신 안 됨 자동배정 후 선수를 추가하고 다시 자동배정해도 빈 슬롯이 안 채워짐 겉으로 보면 “선수 생성이 안 된다"인데, 실제로는 두 개의 독립적인 버그가 동시에 나타난 케이스였다. 증상 정리 조작 기대 실제 선수 추가 폼 제출 목록에 즉시 반영 아무 변화 없음 (새로고침하면 있음) 자동배정 → 선수 추가 → 자동배정 새 선수가 빈 슬롯에 배정 “배정할 선수가 없습니다” or 변화 없음 빈 슬롯 표시 공란 “BYE” 텍스트 노출 버그 1: Turbo Stream 응답 누락 원인 Rails 8 + Turbo 환경에서 form_with는 기본적으로 turbo_stream 포맷으로 제출한다. 컨트롤러의 create 액션이 이렇게 되어 있었다: ...

2026-03-19 · 4분 소요 · Seunghan
Rails 8 Hotwire Native Production Checklist

Rails 8 + Hotwire Native iOS 실전 삽질 체크리스트 — 세션, CSRF, 채팅, 코트맵까지

Rails 8 + Hotwire Native로 iOS 앱을 만들면서 겪은 실전 이슈들을 정리했다. 공식 문서에 안 나오는 것들 위주로. 1. WKWebView 세션 쿠키가 앱 종료 시 날아간다 증상 앱을 완전히 종료(kill) 후 재실행하면 로그인이 풀린다. 원인 Rails 기본 cookie_store는 만료 시간이 없는 세션 쿠키를 생성한다. WKWebView는 앱 종료 시 세션 쿠키를 삭제할 수 있다. 해결 # config/initializers/session_store.rb Rails.application.config.session_store :cookie_store, key: "_app_session", expire_after: 30.days, same_site: :lax expire_after를 설정하면 영속 쿠키가 되어 앱 종료 후에도 유지된다. same_site: :strict는 절대 사용하지 말 것. WKWebView에서 쿠키 전송이 안 된다. ...

2026-03-17 · 5분 소요 · Seunghan
Stimulus DnD Collapse Dashboard

Rails 대시보드에 DnD 카드 순서 변경 + 접기 구현 — SortableJS + Stimulus + CSS 트릭

스포츠 대회 관리 앱의 대시보드에 두 가지 기능을 추가하는 작업이었다. 카드 순서 DnD 변경 — 내 경기 / 대진표 / 경기 목록 카드를 원하는 순서로 재배치 카드 접기/펼치기 — 관심 없는 섹션을 접어 화면을 간결하게 각각은 단순해 보이지만, Turbo Frame lazy loading과 함께 동작해야 하고, 새로고침 후에도 상태가 유지되어야 한다는 조건이 붙으면 신경 쓸 게 늘어난다. 1. DnD 라이브러리 선택 처음에는 native HTML5 Drag & Drop API로 직접 구현했다. dragstart, dragover, drop 이벤트를 다 붙이고 DOM 조작으로 순서를 바꾸는 방식인데, 실제로 동작하게 만드는 건 어렵지 않다. ...

2026-03-17 · 5분 소요 · Seunghan

SVG 대진표에 Stimulus.js로 선수 하이라이트 구현 — Rails 8 + ViewComponent 삽질기

Rails 8 + ViewComponent로 만든 SVG 기반 토너먼트 대진표에 인터랙션을 추가하면서 겪은 내용을 정리했다. 목표는 간단했다: 대진표에서 특정 선수를 클릭하면 그 선수가 출전하는 모든 경기 카드를 색상으로 강조하기. 배경: SVG로 렌더링된 대진표 이 프로젝트의 대진표는 HTML div 카드가 아닌 SVG로 렌더링된다. BracketTreeComponent (ViewComponent)가 각 경기 슬롯 좌표를 계산해 SVG <rect>, <text>, <circle> 등으로 출력한다. <%# bracket_tree_component.html.erb %> <svg width="<%= svg_width %>" height="<%= svg_height %>"> <% slots.each do |slot| %> <% x = x_position(slot.round) %> <% y = y_position(slot) %> <g id="bracket_slot_<%= slot.id %>"> <rect x="<%= x %>" y="<%= y %>" width="216" height="88" rx="10" fill="#fff" /> <text x="<%= x + 46 %>" y="<%= y + 42 %>"><%= team_a_name %></text> <text x="<%= x + 46 %>" y="<%= y + 70 %>"><%= team_b_name %></text> </g> <% end %> </svg> SVG는 HTML과 달리 hover:, ring- 같은 Tailwind 클래스가 직접 먹히지 않는다. 그래서 처음엔 어떻게 접근할지 고민이 됐다. ...

2026-03-17 · 4분 소요 · Seunghan
Bracket FAB Audit Log Rails

대진표에 FAB 피드백 버튼, 수정 권한 체계, Audit Log 붙이기 — Rails 8 삽질 기록

한 번에 세 가지 기능을 동시에 설계하다 보면 서로 얽히는 부분이 생긴다. 이번에는 대진표 관리 앱에 다음을 추가했다. FAB 피드백 버튼 — 우측 하단 플로팅 버튼 → Telegram 전송 역할 기반 대진표 수정 권한 — 대회 vs 친선 모드에 따라 일반 참가자에게 수정 권한 부여 여부 선택 Audit Log — 누가 언제 무엇을 바꿨는지 전/후 데이터와 함께 기록 각각은 단순해 보이지만, 셋을 한꺼번에 설계하다 보니 “어디서 권한을 체크하고, 어디서 로그를 남기고, 어디까지 UI에 노출하는가"에 대한 결정이 계속 붙었다. ...

2026-03-17 · 5분 소요 · Seunghan
AI 에이전트 개발 과정

[개발일기] Rails 8로 AI 에이전트 리뷰 시스템 만들면서 삽질한 이야기

AI가 글을 검수해주는 시스템을 Rails 8로 만들고 있다. 4개의 AI 에이전트가 각자 관점에서 원고를 분석하고, 스토리 데이터베이스와 연동해서 일관성까지 체크하는 구조. 만들면서 꽤 많이 삽질했는데, 기록 안 해두면 까먹을 것 같아서 정리해본다. 1. AI 에이전트의 “톤"이 이렇게 중요할 줄이야 처음엔 에이전트 프롬프트를 이렇게 썼다: 당신은 편집 보조자입니다. 원고를 분석하고 문제점을 지적하세요. 테스트 유저한테 피드백을 받았는데, **“이건 도움이 아니라 채점이다”**라는 반응이 돌아왔다. 창작하는 사람 입장에서 “지적” 톤은 부담스럽다는 거였다. 업계 리서치를 해보니까 Sudowrite, NovelAI 같은 도구들도 “동료” 톤이 압도적으로 선호된다고 한다. ...

2026-03-12 · 7분 소요 · Seunghan
Rails Stimulus DnD Mentor Board Troubleshooting

Rails + Stimulus 드래그앤드롭 멘토 배정 보드에서 만난 삽질 5가지

Rails 8 앱에서 멘토-팀 배정을 드래그앤드롭으로 관리하는 보드를 만들었다. Stimulus 컨트롤러 + fetch + 서버 사이드 HTML 교체 방식이었는데, “되는 줄 알았던” 기능들이 프로덕션에서 하나씩 터졌다. 1. Stimulus 컨트롤러가 아예 로드 안 됨 증상 data-controller="mentor-assignment-board"를 붙였는데 드래그가 안 먹는다. 브라우저 콘솔에 에러도 없다. 원인 importmap-rails를 쓰는 프로젝트에서 한 번이라도 rails assets:precompile을 실행하면 public/assets/ 디렉토리가 생긴다. 이후 개발 환경에서도 Rails는 이 정적 파일을 우선 서빙한다. 문제는 precompile 시점에 존재하지 않았던 Stimulus 컨트롤러들이 public/assets/에 없다는 것. Rails가 public/assets/를 먼저 보기 때문에, app/javascript/controllers/에 있는 새 파일을 무시한다. ...

2026-03-12 · 4분 소요 · Seunghan
ViewComponent Design System Lookbook Migration

ViewComponent 디자인 시스템을 Lookbook으로 이관하면서 만난 삽질들 — Rails 8 + Tailwind CSS 4

Rails 8에서 47개 ViewComponent 기반 디자인 시스템을 warm orange 테마로 전환하고, Lookbook 프리뷰를 전면 구축하면서 만난 삽질들을 정리했다. 배경 기존 프로젝트에는 다음이 갖춰져 있었다: 47개 ViewComponent (input, layout, navigation, card, typography 등 15개 카테고리) CSS Custom Properties 기반 디자인 토큰 (tokens.css) Tailwind CSS 4 + Propshaft 에셋 파이프라인 목표는 BMC(Buy Me a Coffee) 디자인을 레퍼런스로, warm orange 테마 + dark sidebar + stone palette로 전환하고, Lookbook으로 전체 프리뷰를 구축하는 것이었다. ...

2026-03-10 · 4분 소요 · Seunghan
개인정보처리방침 이용약관 면책조항 문의