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
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
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
Rails Sso Turbo Drive Debugging

Rails SSO 구현 중 Turbo Drive가 유발한 두 가지 버그 디버깅

Rails 앱 간 SSO(Single Sign-On)를 HMAC 기반으로 구현하던 중 예상치 못한 두 가지 버그를 만났다. 둘 다 Turbo Drive와 ERB의 동작 방식에서 비롯된 문제였다. 에러 메시지는 동일하게 “state mismatch"였지만 원인은 전혀 달랐고, 첫 번째 버그를 고쳐도 두 번째가 남아 있어 디버깅이 꽤 번거로웠다. 구현 개요 구조 두 개의 독립적인 Rails 앱이 SSO로 연결된다. IdP (Identity Provider): 사용자 인증을 담당하는 Rails 앱. OTP 로그인을 처리하고 One-Time Token을 발급한다. SP (Service Provider): IdP에서 발급받은 토큰으로 로그인하는 Rails 앱. 직접 사용자 자격증명을 다루지 않고 IdP를 신뢰한다. 이 구조는 소규모 멀티 앱 환경에서 공통 인증을 구현할 때 자주 쓰이는 패턴이다. OAuth 2.0보다 단순하지만 CSRF 방지와 토큰 검증은 동일하게 필요하다. ...

2026-02-13 · 7분 소요 · Seunghan
Rails Turbo Actioncable 500 Debug

Rails Turbo Stream 500 에러 3종 세트 디버깅 — broadcast, SolidCable, Telegram Markdown

Rails 8 + Hotwire(Turbo) 기반 앱을 운영하다 보면 broadcast_append_to 계열 콜백이 조용히 500을 내뱉는 경우가 있다. 거기에 SolidCable 초기 설정 문제와 Telegram Bot 메시지 파싱 오류가 겹치면 로그 해석도 헷갈린다. 이번에 세 가지가 한꺼번에 터져서 순서대로 해결한 과정을 정리한다. 이 글에서 다루는 세 문제는 서로 독립적이지만, 실제 운영 환경에서는 이렇게 한꺼번에 맞닥뜨리는 경우가 많다. 각 문제를 격리해서 하나씩 해결하는 접근이 중요하다. 문제 1: No unique index found for id — broadcast 콜백 500 현상 메시지나 알림을 생성할 때 컨트롤러에서 500이 발생한다. 로그를 보면: ...

2026-01-09 · 7분 소요 · Seunghan
Rails Stimulus Controllers Lookbook Debug

Rails + Stimulus 컨트롤러 11개 구현기: 스크롤·캐러셀·텍스트 애니메이션

Rails + ViewComponent + Lookbook 조합으로 컴포넌트 라이브러리를 만들 때, Stimulus 컨트롤러가 전부 스텁(빈 껍데기) 상태로 남아있는 상황을 맞닥뜨렸다. 13개 컨트롤러 중 3개만 동작하고 나머지 10개는 connect() {} 한 줄짜리였다. 이걸 전부 구현하면서 겪은 삽질을 정리한다. 이 글은 단순히 코드를 붙여넣는 게 아니라, 각 컨트롤러를 구현하면서 왜 그런 방식을 선택했는지, 어떤 문제가 발생했는지, 그리고 어떻게 해결했는지에 초점을 맞춘다. 구현 대상 총 11개 컨트롤러를 4단계로 나눠서 구현했다. 복잡도와 의존성을 기준으로 순서를 정했다. DOM 직접 조작 → 스크롤 연동 → RAF 애니메이션 → 인터랙티브 캐러셀 순서로 진행하면 각 단계에서 배운 패턴이 다음 단계에 자연스럽게 이어진다. ...

2025-11-18 · 11분 소요 · Seunghan
개인정보처리방침 이용약관 면책조항 문의