Languages/Ruby or Rails2008.08.01 13:36

이 문제는 나그네 님께서 지적해주신 문제입니다. 최신 버전의 Rails는 일반 html 파일에 포함된 form의 input 필드들과 연동할때, 약간의 문제가 있습니다.

가령 Beginning Ruby on rails의 5장에 수록된 예제처럼 input.html 파일을 다음과 같이 만들었다고 해 봅시다.

<html>
<body>
    <form action="/look/at">
    <input type="text" name="text1"/>
    <input type="submit"/>
    </form>
</body>
</html>

이 form에 뭔가를 입력하고 submit 버튼을 누르면 /look/at 액션이 실행될 것이고, 그 결과가 화면에 출력될 것입니다. 그런데 그냥 이렇게만 하면 별 문제가 없다가, 위의 html 코드를 다음과 같이 바꾸면 문제가 발생합니다.

<html>
<body>
    <form action="/look/at" method="post">
    <input type="text" name="text1"/>
    <input type="submit"/>
    </form>
</body>
</html>

위와 같이 바꿔놓고 submit  버튼을 눌러보면, 다음과 같은 오류가 발생하는 것을 볼 수 있습니다.

ActionController::InvalidAuthenticityToken in LookController#at

액션 컨트롤러 쪽에서 AuthenticityToken이라는 것을 요구하는데 그게 없기 때문에 발생하는 오류입니다. 이 문제를 좀 더 정확하게 이해하기 위해, 다음과 같이 해 봅시다. 일단 controller Look에 input이라는 액션을 추가합니다.

class LookController < ApplicationController
    def at
        @data = params[:text1]
    end

    def input
    end

end

그런 다음 위의 html 코드를 다음과 같이 바꾸고, app/views/look 아래에 input.html.erb 라는 이름으로 복사해 넣습니다.

<html>
<body>
    <% form_tag '/look/at', :method=>:post do %>
    <input type="text" name="text1"/>
    <input type="submit"/>
    <% end %>
</body>
</html>

그런 다음에, 브라우저로 /look/input을 엽니다. 그리고 나서 브라우저의 소스 코드 보기 기능을 통해 소스 코드를 봅시다. 다음과 같이 되어 있는 것을 볼 수 있습니다.

<html>
<body>
 <form action="/look/at" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="8f846ee3232eda791b4bf4c9d6d0a20478afcf8a" /></div>
 <input type="text" name="text1"/>
 <input type="submit"/>
 </form>
</body>
</html>

결국, /look/at은 method가 post일때 위의 token이 오기를 기대하는데 안오니까 불평을 해 댔던 것이죠. 이 문제를 해결하는 방법은 두가지가 있는데, 위에서처럼 모든 form 태그를 전부 form_tag 메소드를 써서 생성하는 것입니다. 그러면 알아서 넣어주니까 괜찮죠.

하지만 <div> 태그가 원래 원칙적으로 line break를 유발하는 습성이 있기 때문에, 웹 디자이너에게는 솔직히 짜증나는 부분이 될 수 있습니다. 그냥 hidden input filed로 두면 되었을텐데 div는 뭐하러 두었는지 참 ㅋㅋ

가장 간단한 해결책은 CSRF(Cross-Site Request Forgery) 공격을 막기 위해 도입된 위 feature를 강제로 동작하지 않도록 만드는 것입니다.

위의 경우라면, 컨트롤러 Look에 다음의 한줄을 넣어주세요.

skip_before_filter :verify_authenticity_token

제가 Beginning Ruby on Rails를 번역하면서 원저자가 책을 썼던 시점에 비해 바뀐 부분을 반영해 넣느라 고민을 좀 했었는데, 이렇게 책을 내놓고 보니 또 그 와중에 뭔가 새로운 기능이 계속 추가가 되어서 -_-;;

어쨌던 불편을 끼쳐드려서 죄송합니다. 앞으로도 이런 부분을 발견할 때 마다, 그리고 독자 분들의 질문이 있을 때 마다 가능한한 열심히 답변을 드리도록 하겠습니다.


신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. 전 원인도 모르고 그냥 첫번째 방법 썼는데 ^^ 좋은 정보 감사합니다~

    2008.08.01 14:26 신고 [ ADDR : EDIT/ DEL : REPLY ]

Languages/Ruby or Rails2008.07.17 14:47

passenger를 설치하는 절차는 우선 다음의 명령을 입력하는 것으로 시작된다.

sudo gem install passenger

엔간하면 이 절차는 정상적으로 완료될 것. 하지만 그 다음이 문제. 설치 문서에는 passenger-install-apache2-module 을 실행하라고 나오는데, 이 파일은 /var/lib/gems/1.8/gems/passenger-2.0.2/bin 디렉터리 아래에 있는데다, 결정적으로 실행 권한이 설정되어 있지 않다.

그러므로 실행하려면 그 디렉터리 아래에 가서, sudo ruby passenger-install-apache2-module 처럼 실행해 주어야 한다. 그런데 그렇게 실행해 보면, rake가 gems 디렉터리 아래에 분명 설치되어 있는데도 설치되어 있지 않다고 불평하는 일이 발생한다. (이런...)

이런 일이 발생했다면, 여러분의 gems installation에 뭔가 문제가 발생한 것이다. -_-;
http://agileweb.wordpress.com/2008/07/18/how-to-install-rails-21-on-ubuntu-in-5-steps/
위의 링크를 참조해서 여러분의 gems installation 자체를 업데이트해보는 것이 좋겠다. 그런 다음 rails, passenger 등등을 다시 설치해야 한다.

이것은 rake 실행파일이 /usr/bin/ 아래에 복사되어 있지 않기 때문에 발생하는 문제. 따라서 sudo cp /var/lib/gems/1.8/gems/rake-0.8.1/bin/rake /usr/bin 과 같이 해주어야 한다. 그러면 문제가 해결된다. (카피가 찜찜한 분은 심볼릭 링크를 걸어주는 편이 낫겠다.) 실행권한도 빠져있으니 sudo chmod +x로 걸어주어야 한다.

이렇게 하고 나서 다시 sudo passenger-install-apache2-module 를 해 보면 뭔가 make 한다는 메시지가 쫙 나오고 나서 다음과 같은 텍스트가 화면에 출력된다.

Please edit your Apache configuration file, and add these lines:

   LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-2.0.2/ext/apache2/mod_passenger.so
   PassengerRoot /var/lib/gems/1.8/gems/passenger-2.0.2
   PassengerRuby /usr/bin/ruby1.8

After you restart Apache, you are ready to deploy any number of Ruby on Rails
applications on Apache, without any further Ruby on Rails-specific
configuration!

Press ENTER to continue.

/etc/apache2/conf.d 디렉터리 아래에 passenger라는 파일을 만들어 위의 설정을 그대로 입력해 보자. 그런 다음에 enter 키를 누르면 다음의 텍스트가 화면에 출력된다.

Deploying a Ruby on Rails application: an example

Suppose you have a Ruby on Rails application in /somewhere. Add a virtual host
to your Apache configuration file, and set its DocumentRoot to
/somewhere/public, like this:

   <VirtualHost *:80>
      ServerName
www.yourhost.com
      DocumentRoot /somewhere/public
   </VirtualHost>

And that's it! You may also want to check the Users Guide for security and
optimization tips and other useful information:

  /var/lib/gems/1.8/gems/passenger-2.0.2/doc/Users guide.html

Enjoy Phusion Passenger, a product of Phusion (www.phusion.nl) :-)
http://www.modrails.com/

Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.

일단 여기까지 해서 설치는 끝났다. 이제 남은 일은 VirtualHost 설정을 적절히 해서 Rails의 실행 결과가 브라우저에 전송될 수 있도록 하는 것 뿐...

우선, apache에 또다른 VIrtualHost 설정을 꾸며서, 접속 도메인 명이 달라질 경우 해당 VirualHost가 실행될 수 있도록 한다.

<VirtualHost *>
    ServerAdmin byungjoon.lee@gmail.com
    ServerName www.xxxxx.com
    DocumentRoot /home/bjlee/work/rails/xxxxx/public
    RailsBaseURI /
</VirtualHost>

대략 위와 같이 하면 된다. 다만 한가지 주의할 것은, 위의 /home/.../public 디렉터리에 www-data (apache2가 실행되는 사용자명) group에 대한 읽기쓰기 권한을 주어야 한다는 것. 필자는 /home/.../work/rails 디렉터리에 가서 그 아래에 있는 모든 subdirectory에 대해 chown -R bjlee:www-data *를 실행하고, chmod -R g+w * 를 실행해 주었다.

이렇게 하고 나서 브라우저의 주소창에 www.xxxxx.com을 입력하고 접속해보면 접속이 된다. 접속이 안될 경우 해당 도메인 명이 등록이 안된 것이니 ㅋㅋ 윈도우의 hosts 파일을 고쳐서 등록된 것처럼 꾸며야 할 것.

그런데 이렇게 하면서 몇가지 프로그래머가 반드시 알아야 할 사항이 드러났는데.

1. development 모드에서는 *.rhtml의 확장자를 사용해 view template을 꾸밀 수 있었는데, production mode를 가정하는 passenger의 특성상 *.html.erb의 확장자가 아니면 인식을 못한다는 것. (Rails 2.0부터는 *.rhtml의 확장자는 더이상 사용하지 않으며, *.html.erb의 확장자를 사용해야 한다. 다만 현재로서는 하위호환성을 위해 *.rhtml을 Development 모드에서는 지원하고 있다.)

2. 원래 그런 건지 아니면 설정을 잘못해서 그런건진 몰라도 (아마 전자일듯) passenger를 사용해 rails 프로그램을 띄우면 소스코드를 바꿔도 그 결과가 바로 반영되어 실행되지는 않는다. (소스코드의 변경을 반영하려면 웹 서버를 다시 띄워야 한다.) 아마 production mode 로 release를 하는 것을 가정하는 passenger의 특성상 그러할 것. 물론 시간이 지나 모든 세션이 종료되고 난 뒤에는 수정된 코드가 다시 반영된다. :-) Rails app 디렉터리 아래에 tmp/restart.txt 파일을 'touch' 해도 된다. 이 경우에는 웹 서버 전체가 재시작되는 것이 이니라, 해당 app만 재시작된다.

여기까지만 주의하면 passenger를 통해 rails 프로그램을 쾌적하게 배포할 수 있을 것이다.

다른 문제에 대해서는 passenger를 배포하고 있는 웹 사이트에 가서 http://www.modrails.com/ 사용자 가이드를 보면 될 것이다.


신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Languages/Erlang2008.06.14 17:03
Erlang 웹 개발을 위해 yaws 서버 소스 파일을 다운로드 받아 설치할때는 다음과 같은 절차를 우선적으로 밟게 된다.

./configure ; make

그런데 ./configure를 실행하면 gcc에서 실행파일을 생성할 수 없다고 하는 메시지가 뜨면서 configure가 중단되는 경우가 있다.

그런 경우에는 이 글을 참고하여 gcc 문제를 먼저 해결해야 한다. 그런 다음에 다시 ./configure ; make 한다.

그런데 make를 진행하다 보면 pam_appl.h라는 헤더 파일을 찾지 못한다는 오류 메시지가 출력되면서 컴파일이 진행되지 않는 경우가 있다.

그런 경우에는 sudo apt-get install libpam0g-dev 를 실행하여 관련된 헤더 파일을 설치하여야 한다.

이상의 과정이 정상적으로 끝났다면 이제 ./configure ; make를 하면 yaws 파일이 정상적으로 생성된다.

생성된 실행 파일을 설치하는 것은 그 나중 문제인데, 사용자의 local home directory에 임시로 설치하여 사용하고자 한다면 그 상태에서 make local_install 하면 된다. 그러면 실행 파일이 사용자의 $HOME/bin에 설치되고, configuration 파일은 $HOME/yaws.conf와 같이 만들어지게 된다.

개발 단계에서는 이렇게 설치해놓고 사용하는 것이 보다 간편하다.

상기 문제는 yaws 소스를 컴파일하여 설치하려고 하는 경우에만 발생하며, sudo apt-get install yaws와 같이 해서 설치한 사용자에게는 발생하지 않는 문제이다. 다만 sudo apt-get install yaws로 설치한 사용자는 Yaws 사용자 가이드에 나온 예제들을 실행해 보기 위애서 여러 가지 설정 파일들을 이리 고치고 저리 고치는 수고를 좀 장시간 해 주어야 할 것이다.

참고한 링크들:

  1. http://marc-abramowitz.com/archives/2007/04/18/building-yaws-erlang-web-server-for-ubuntu/
  2. http://www.buggymind.com/137
  3. http://www.ibm.com/developerworks/kr/library/opendw/20080520/





신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Languages/Ruby or Rails2008.06.13 10:03

제가 번역했던 Beginning Ruby on Rails 책을 구매하신 분중 두 분깨서 다음과 같은 오류를 지적해 주셨습니다. 해결책을 포스팅하겠다고 약속했었는데 늦어서 죄송합니다.

이 문제는 Rails가 sqlite3를 기본 database로 사용하게 되면서 빚어진 문제입니다. MySQL을 데이터베이스로 사용하려면 rails <app name> --database=mysql 과 같이 해주어야 합니다. 그렇게 하지 않으면, 지적된 오류가 발생하게 됩니다.

Windows

Ruby 1.8.6 버전을 Windows에 설치한 다음 gem을 통해 rails를 설치하고 Rails 프로그램을 만들어 돌려보면 no such file to load -- sqlite3 라는 오류가 발생하는 것을 보게 됩니다. 이 오류의 원인은, Rails가 sqlite3를 기본적으로 설치하지 않는데서 빚어지는 것입니다. 따라서, 이 오류를 교정하기 위해서는 다음과 같은 절차를 밟아야 합니다. sqlite3를 설치하기 위한 절차입니다. 현재로서는 Windows에서 발생한 경우만 확인되었으므로, Windows에서의 해결방법을 기준으로 말씀드리겠습니다.

1. http://www.sqlite.org/download.html을 방문합니다.

2. 화면 좌측의 Precompiled Binaries for Windows 섹션에서 sqlite-3_5_9.zip과 sqlitedll-3_5_9.zip의 두 파일을 다운로드 받습니다. 이 두 파일의 압축을 ruby 설치 디렉터레 아래의 bin 이라는 이름의 서브디렉터리에 풀어 놓습니다. 그 결과 해당 디렉터리 아래에 sqlite3.exe sqlite3.dll sqlite3.def의 세 가지 파일이 생겨있어야 합니다.

3. 그런 다음에 명령행에서 gem install sqlite3-ruby를 실행합니다. 화면에 여러 가지 옵션들이 나오게 될텐데, 1번 옵션에 나오는 sql3-ruby 1.2.2 (mswin32)를 선택합니다.

Bulk updating Gem source index for: http://gems.rubyforge.org
Select which gem to install for your platform (i386-mswin32)
 1. sqlite3-ruby 1.2.2 (mswin32)
 2. sqlite3-ruby 1.2.2 (ruby)
 3. sqlite3-ruby 1.2.1 (mswin32)
 4. sqlite3-ruby 1.2.1 (ruby)
 5. Skip this gem
 6. Cancel installation
> 1

위와 같이 하면 이제 sqlite3가 설치될 것입니다. 여기까지 하면 sqlite3 관련 오류는 해결이 되어야 합니다.

Linux (Ubuntu)

Ubuntu에서는 원래

sudo apt-get install sqlite3
sudo gem install sqlite3-ruby

위의 두 과정이 제대로 수행되면 문제가 없이 되어야 합니다.
그런데 간혹 두 번째 명령을 실행하다가 no such file to load -- mkmf 라는 메시지가 나오면서 설치가 제대로 안되는 경우가 있습니다. 그런 경우에는

sudo apt-get install ruby1.8-dev

위의 명령을 먼저 실행해 줍니다.

그런 다음 다음과 같이 하면 됩니다.

bjlee@bjlee-ubuntu804:~$ sudo gem install sqlite3-ruby
Select which gem to install for your platform (i486-linux)
 1. sqlite3-ruby 1.2.2 (mswin32)
 2. sqlite3-ruby 1.2.2 (ruby)
 3. sqlite3-ruby 1.2.1 (mswin32)
 4. sqlite3-ruby 1.2.1 (ruby)
 5. Skip this gem
 6. Cancel installation
> 2

그러면 다음과 같은 메시지가 주욱 나오면서 설치가 될 것입니다.

Building native extensions.  This could take a while...
Successfully installed sqlite3-ruby-1.2.2
Installing ri documentation for sqlite3-ruby-1.2.2...
Installing RDoc documentation for sqlite3-ruby-1.2.2...

이제 웹 서버를 내렸다가 다시 올리기만 하면 문제가 해결되어야 합니다.

감사와 사죄의 말씀

이 오류를 지적해주신 분은 킹상수님과 딸기벌레님, 두분입니다. 답변은 구글에 문의하면 찾을 수 있는 내용이긴 합니다만, 제가 빠른 답변을 드리겠다고 해 놓고 답을 제때 못드려서 죄송하다는 말씀, 다시한번 드립니다.

질문주신 두분께는 메일로 따로 연락드리도록 하겠습니다.



신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. 까아~

    이게 문제였군요!! ㅠㅠ 안되서 설치만 여러번 한것 같아요...
    감사합니다. ^ㅡ^ 책은 구매해서 잘 보고있어요. 행복한 하루 되세요..

    2008.08.29 10:08 신고 [ ADDR : EDIT/ DEL : REPLY ]

Books by Example/SICP2007.11.09 00:13
밤마다 한시간씩 SICP 문제를 풀어보고 있습니다. 오늘은 1.8을 풀어봤습니다. Scheme 언어에 익숙해지려면 아무래도 시간이 좀 많이 걸리겠군요. 문제 1.8은 이렇습니다.

세제곱근 cube root를 구하는 뉴튼 법은, x의 세제곱근에 가까운 값을 y라고 할 때 다음 식에 따라 y보다 더 가까운 값을 계산하는 것이다.

(x + y^2 + 2y) / 3

제곱근 프로시저처럼, 이 식을 써서 세 제곱근 프로시저를 짜보자.


글쎄 뭐 짜는 것 까지는 좋습니다. 다음과 같은 코드를 작성했습니다.

(define (cube_root x)
  (if (or (= x 0) (< x 0)) 0 (cube_root_iter 1.0 x)))

(define (cube_root_iter guess x)
  (if (good_enough? guess x) guess (cube_root_iter (improve guess x) x)))

(define (good_enough? guess x) (< (/ (abs (- (cube guess) x)) x) 0.01))

(define (cube x) (* x x x))

(define (improve y x) (+ (/ x (* 3 (* y y))) (/ (* 2 y) 3)))

(cube_root 5)


이 간단한 코드를 짜는 데만도 한시간이 걸렸습니다. 그런데 처음에는 이상하게 값이 잘 안나오고 무한루프에 빠지더군요. 의심가는 데가 있어서 google에게 물어봤는데, 아무래도 책(번역판)에 나온 뉴튼법 공식이 좀 잘못된 것 같습니다. 다음과 같이 되어야 할 것 같습니다. (책에 나온 수식의 첫 번째 +가 /로 바뀌면 됩니다.)

사용자 삽입 이미지

위의 코드에서 빨간색으로 표시된 부분이, google이 알려준 뉴튼법 공식에 따라 수정된 부분입니다. 이렇게 고치고 나니, 프로그램이 정상적인 결과를 내 놓았습니다.

이 오류가 한글판의 오류인지 아니면 원서의 오류인지 잘 모르겠어서 구글신에게 다시 물어봤습니다. 한글판의 오류입니다. -_-; 좋은 책입니다만, 40페이지를 넘어가기도 전에 오류를 하나 발견하고 나니 어쩐지 맥이 빠지는 기분입니다[각주:1].

이런 기분인거냐?

이런 기분인거냐?



아무튼, 매일 잠들기 전에 하나씩 풀어볼 문제가 생겼다는건 기분 좋은 일이로군요. 아 이제 선형 대수학 책도 봐야하는데... -_-
 

  1. 역자분들의 노고를 폄하하거나 할 의도가 없음을 밝혀둡니다. 어쨌든 좋은 책이고, 사람이란 실수를 하게 마련이니까요. [본문으로]
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. Programming Pearls 를 다 보고 이 책을 보려고 작정하고 있습니다. 나중에 연습 문제 풀 때 여기 자주 와야 되겠네요. 전 이거 두권이면 올 겨울은 그냥 지나갈 듯 합니다. ㅎㅎ

    2007.11.09 10:29 신고 [ ADDR : EDIT/ DEL : REPLY ]
  2. 명백한 오타네요. ㅡㅡ;;
    사람의 일이라 피하기 힘들다지만... 이런 사항이 보고될 때마다 가슴이 두근두근 댑니다.
    또 다른 대형 사고는 없는지.... 얼마나 더 지나야 안심할 수 있을런지.... 휴~

    지적하신 사항은 오탈자 사이트에 반영해 놓겠습니다.

    2007.11.09 15:48 신고 [ ADDR : EDIT/ DEL : REPLY ]
  3. 어쩐지 제가 뉴튼법으로 구한 식과 책에 적혀있는 것이 다르다고 했습니다.OTL....

    2007.12.18 12:35 신고 [ ADDR : EDIT/ DEL : REPLY ]
  4. 저도 같은 일을 겪었어요. 어쩐지 값이 안 나와서 뒷장의 뉴튼 부분을 참고하니 풀리더라고요. :)

    2008.08.31 15:44 신고 [ ADDR : EDIT/ DEL : REPLY ]