웹 어플리케이션에서 데이터 입력 form을 만들어서 데이터를 저장하는 작업은 매우 일반적인 작업입니다. 그리고 사용자가 입력한 데이터는 parameters를 이용해서 저장됩니다. Rails도 당연히 이 방식을 따릅니다. 다만 parameter를 넘겨주는 방식이 다른 프레임워크와 다른 면이 있어서, MVC 기반의 프레임워크에서 일반적으로 사용하는 방법으로는 문제가 발생할 수 있습니다.
이 포스팅에서는 내가 form을 잘 만들었다고 생각하고, parameter를 넘겼는데 생길 수 있는 문제 중 흔히 보이는 3가지 문제들과 그 해결방법에 대해 알아보겠습니다.
1. token과 관련된 문제(unexpected token)
이 오류는 아직 rails에 익숙하지 않아서 rails form을 사용하지 않고, html 태그를 사용하는 분들이 흔히 보는 오류 메세지입니다.(사실 저도 아직 잘 못 씁니다..) Rails에서는 기본적으로 입력 form을 생성할 때 보안을 강화하기 위해 문자열 인코딩 정보와 token이라는 일종의 암호문을 함께 전송합니다. 그런데 이 두가지는 rails에서 제공하는 form helper로 전송할 때는 자동으로 생성되지만, html태그로 전송될 때는 자동으로 생성되지 않습니다.
간단한 예시로 무엇이 문제인지 알아보겠습니다.
Rails는 기본적으로 html에서 사용하는 form 이외에 자신들만의 form을 가지고 있습니다. 위에서 보는 <%= form_tag do %>가 대표적인 예시입니다. 위의 form은 아무 input이 없는 form처럼 보이지만 사실 rails form은 기본적으로 인코딩 정보와 token을 보이지 않게 같이 전송합니다. 그래서 위의 form은 실제로는 아래와 같은 form을 만듭니다.
굳이 인코딩 정보와 token을 넣는 이유는 보안을 강화하기 위해서입니다.
해결방법
해결방법은 간단합니다.
rails form을 익히고, 사용하기(권장)
application_controller 수정하기
1. Rails form을 익히고, 사용하기(권장)
먼저 rails form을 잘 익히고 사용하는 방법이 가장 좋습니다. 굳이 강화된 보안을 무시하면서 html태그를 사용할 필요는 없다고 생각합니다. Rails form_tag 관련 문서 앞의 링크의 문서처럼 rails form tag과 html form tag를 잘 비교하면서 설명한 문서가 있습니다. rails를 더 잘 쓰시려면 배우는 것이 필수입니다. 익숙해지면 html tag보다 더 편리합니다.
2. Application_controller 수정하기
다음 방법은 권장하지는 않는 방법입니다만, 보안 체크를 꺼버리는 방법이 있습니다.app/controllers/application_controller.rb에 가보시면 다음과 같은 코드가 기본적으로 설정되어 있습니다.
여기서 4번째 줄의 protect_from_forgery with: :exception부분을 주석처리해주면 token관련 오류는 보지 않을 수 있습니다. 하지만 거듭 강조하지만 보안도 개발자가 고려해야 하는 것중 하나이기 때문에, 이는 권장하지 않는 방법입니다. 구글에 rails form 관련 문서를 꼭 읽어보세요.
2. Strong parameter
strong parameter 문제는 scaffold로 app을 만들었을 때 흔히 나오는 문제입니다. 다음은 scaffold로 post를 만들었을 때의 post controller입니다.
위의 19번째 줄을 보면(@post = Post.new(post_params)), rails는 parameter를 post_params로 묶어서 처리합니다. 그리고 해당 parameter는 59번 째 줄에서 만들어집니다.
이와 같은 방식을 strong parameter를 사용한다고 말합니다. 즉, rails는 기존의 사용자가 넘겨준 데이터를 보안상의 이유로 곧이곧대로 믿는 것이 아니라, 사용자가 보내주는 데이터가 우리가 구성한 db에 맞는 데이터가 들어 온 것인지 한 번 더 확인합니다. 그래서, rails는 :title, :content만 form이 받아들이는 데이터로 인식하고 그 이외의 데이터는 저장하지 않습니다. 따라서, DB를 수정할 경우에(table에 새로운 column을 추가하는 경우) 해당 strong parameter도 같이 수정해주어야 합니다.(rails 4에서는 rake db:migrate add_column_to_table ~와 같은 명령어로 자동 수정이 안 됩니다.)
3. DB와 Schema.rb 불일치 문제
마지막으로 migration과 관련된 문제입니다. 이 문제도 strong parameter처럼 오류 메세지를 뿜지 않습니다. 그래서 log쪽에서 확인을 해야하는 문제인데요. rake db:migrate를 통해 만든 db 구성과 schema.rb에 만들어진 db 구성이 다를 때, form 데이터는 저장되지 않습니다.(사실 어떤 데이터든 db에 저장이 안됩니다.)
&nbps;Schema.rb는 db table을 모두 조감하는 하나의 db 밑그림입니다. 처음부터 있는 파일을 아니고 rake db:migrate하면 생기는 db 폴더에 생성됩니다.
눈여겨 볼 부분은 12번 째 줄에서 # It's strongly recommended that you check this file into your version control system. 에서 볼 수 있듯이 직접 저 파일을 수정해서는 안 된다는 것입니다. 일반적으로 schema.rb와 db table간의 차이는 잘 안 생깁니다. 자주 있는 문제는 아니라는 거죠. 그렇지만, 차이가 생겼을 때는 이를 맞춰주어야 합니다. 이 때는
명령어를 사용합니다. 이 명령어는 현재 우리가 만든 db 구성에 schema.rb 파일을 재구성해주는 명령어입니다.