Tag Archives: Table

Rails form_for에서 STI(Single Table Inheritance) 문제 해결하기

rails_logo

레일의 폼헬퍼는 폼을 만드는 과정을 정말 쉽게 해결해 주는 마법사같은 역할을 합니다. 확실히 레일즈에서 라우트와 폼헬퍼의 유기적인 동작을 보면 왜 레일즈가 유명한지 실감하게 되는것 같습니다. 오늘 겪었던 STI로 인해 폼헬퍼의 form_for가 정상적으로 동작하지 못하는 문제의 해결방법을 기록차 정리합니다.

사실 문제를 해결하는 방법은 없습니다. 기본적으로 form_for가 유입경로에 따라 어디로 라우팅 해야 하는지를 자동으로 결정해 주지만 STI를 사용한 Model의 핸들링의 경우 수동으로 처리해 주어야 합니다. 심지어 홈헬퍼 레퍼런스에서도 이렇게 설명하고 있습니다.

sti_problems_form_for

결과적으로 :url과 :method를 이용하여 명시적으로 어디로 라우팅할지를 결정해 주어야 한다는 것입니다. Project라는 이름의 Model을 수정하는 경우라고 가정할 때 컨트롤러는 다음과 같습니다.

def edit
   @project = Project.find(params[:id])
end

그리고 뷰에서 form_for를 활용하는 코드는 다음과 같습니다.

<% form_for(@project, :as => :project, :url => {:controller => "projects",:action => "update"}) do |f| %>
    ...
    <%= submit_tag 'Update' %>
<% end %>

:url 설정에서 컨트롤러와 액션을 직접 선택한것을 볼 수 있습니다. 이 설정을 통해 적절한 method가 선택되며 라우팅 문제는 이것으로 해결할 수 있습니다. 하지만 project_TYPE_FIELDNAME처럼 데이터가 이상하게 들어오는 문제가 남아있습니다. 이부분은 :as를 통해 모델을 재정의할 수 있습니다.

참고

[MySQL] MyISAM 방식의 테이블 복원하기

MySQL을 운영하다 보면 겪는 테이블 손상 혹은 크래시 문제를 결국에는 겪게 되는것 같습니다. 이것을 피하기 위해 잦은 백업도 필요할 것이고 문제 발생시에 복구 절차에 대해서도 항상 고민해 두어야 할것 같습니다. DB 복구는 DB운영시와 DB비운영시 두가지를 생각해 볼 수 있습니다.

1. MySQL 구동시

MySQL을 구동중이라면 MySQL에 접속하여 직접적으로 쿼리를 날리면 됩니다.
[code]CHECK TABLE {TABLE NAME}[/code]
위와같은 쿼리를 사용하면 테이블의 상태가 나옵니다. 보통 Status OK가 나오게 되며 큰 문제가 아닐 경우 Warning이 뜹니다. 하지만 문제가 심각할 경우 Error가 발생하게 됩니다. 이 Error가 발생한다면 꼭 문제를 해결하셔야 합니다.
[code]REPAIR TABLE {TABLE NAME}[/code]
위의 쿼리문으로 대부분의 문제는 해결될 수 있습니다. 복구하는김에 다음의 두가지 명령을 추가로 사용하여 테이블 상태를 정리해 주도록 합시다.
[code]OPTIMIZE TABLE {TABLE NAME}
ANALYZE TABLE {TABLE NAME}[/code]
이렇게 MySQL구동시에 작업을 해야 한다면 해당 테이블의 접근이 철저하게 봉쇄된 상태에서 해야 합니다. 될수 있으면 운영중인 서비스는 내리시길 권합니다.

2. MySQL 비구동시

MySQL이 비구동중이라면, 다른말로 MySQL이 구동중이 아니어야만 할 수 있는 복구 방법입니다. myisamchk라는 툴을 사용을 합니다. 이 툴은 MySQL설치시에 같이 설치 됩니다. 이 방법은 될 수 있으면 MySQL을 종료한 상태에서 수행하길 권합니다. (구동중에 수행해서 큰 문제는 없어보이긴 하지만 모두들 종료하길 권하더군요)
테이블명.*를 입력하려면 DB가 저장된 디렉토리 안에 들어가 데이터베이스명의 디렉토리 안으로 들어가셔서 수행을 하셔야 합니다.
[code]myisamchk -r {TABLE NAME}.*[/code]
위의 명령이 가장 기본적인 복구 명령입니다. 상황에 따라 다음과 같은 복구 옵션을 사용할 수 있습니다.
[code]myisamchk -o {TABLE NAME}.*[/code]
위의 o옵션은 안전모드에서 수행하라는 뜻이며 r옵션보다는 느리지만 좀 더 안정적으로 복구를 할 수 있다고 합니다. 또한 r에서 고치지 못하는 것을 추가적으로 고치기도 합니다.

3. 강제로 복구하기

위의 다양한 방법으로 복구되지 않을 경우 도전해 볼만한 강제적인 방법이 있습니다.
[code] myisamchk -r -f {TABLE NAME}.*[/code]
위의 방법을 시도하기 전에 꼭 백업을 해두시길 바랍니다.