Tag Archives: Guestbook

[Ruby] IntelliJ에서 Rails를 이용한 간단한 방명록 만들어보기

rails_logo

요즘 열심히 레일즈 공부를 하고 있습니다. 사실 열심은 아닌것 같네요. 백문이 불여일견 뭔가 한번 해보는게 좋지 않을까 싶어 간단한 방명록을 혼자 만들어보기를 해보기로 하였습니다. 그 과정을 기록해 볼테니 저같은 시작하시는분들에게 참고 자료가 될 수 있다면 좋겠네요.

이 기록은 Rails기반의 개발이 가능한 제트브레인사의 IntelliJ 또는 RubyMine기반에서 개발한다는것을 가정하고 기록하고자 합니다. 또한 맥기반에서 개발하고 있기에 윈도우 환경과는 차이가 조금 있을수도 있습니다.

making_guestbook_using_rails_1

IntelliJ를 실행한 뒤에 새로운 프로젝트를 생성하기 위해 Create New Project를 선택합니다.

making_guestbook_using_rails_2

Ruby 플러그인을 선택한 뒤에 적절한 프로젝트를 생성합니다. 저는 그냥 대충 guestbook이라고 만들어보겠습니다.

making_guestbook_using_rails_3

이번엔 적절한 SDK를 선택해줍니다. 아무것도 없다면 Configure에 들어가 설치되어있는 Ruby를 선택하여 추가해 주면 됩니다.

making_guestbook_using_rails_4

왼쪽의 Ruby on Rails를 선택한 다음에 적절한 Rails Version을 선택해 줍니다. 아무것도 없을 경우 Install Rails Gem…을 선택하여 적절한 Rails를 설치해주면 됩니다.

making_guestbook_using_rails_5

이제 프로젝트가 세팅되고 자동으로 bundle install까지 실행됩니다.

making_guestbook_using_rails_6

이런식으로 “Your bundle is complete!”라는 문구가 보이면 프로젝트의 초기화가 끝난것입니다.

making_guestbook_using_rails_7

오른쪽 상단의 플레이 모양 버튼을 누르면 WEBrick 기반의 서버가 시작됩니다. 정상적으로 실행된다면 콘솔에 보이는것과 같은 로그가 출력됩니다. 이제 브라우저를 통해서 http://localhost:3000 에 접속해 보겠습니다.

making_guestbook_using_rails_8

위와 같은 기본 페이지를 볼 수 있습니다. 여기서 무언가 친절한 설명이 나오고 있군요. 저 설명대로 진행을 해보겠습니다.

making_guestbook_using_rails_9

New – Run Rails Generator를 실행해 봅니다. 간단하게 Option – G를 눌러도 됩니다.

making_guestbook_using_rails_10

컨트롤러를 먼저 만들까 모델을 먼저 만들까 고민을 많이 했습니다만, 가이드의 순서가 뭔가 의미가 있지 않을까(?) 생각되어 모델부터 만들어 보겠습니다. 검색을 통해 빠르게 무엇을 생성할것인지를 선택할 수 있습니다.

making_guestbook_using_rails_13

Generate arguments 의 내용을 참고하여 필요하다고 생각되는 항목을 적어보았습니다. 사용자의 정보인 name, email이 있고 내용을 수정 삭제하기 위한 password와 방명록 글 내용인 content를 추가하였습니다. 여기서 예시에 [ ]를 보고 대괄호를 해줘야 하는줄 알았는데 Optional의 의미더군요;;

Rails는 단수복수의 구분이 매우 중요합니다. 모델을 생성할 때 단수로 생성한것을 주의깊게 봐두세요.

making_guestbook_using_rails_12

오류 없이 정상적으로 필요한 것들이 생성되었습니다. DB 마이그레이션 작업을 수행하여보겠습니다. 기본적으로 Development환경에서의 데이터베이스 설정은 sqlite로 구성되어있습니다. 아쉬운데로 그냥 진행해보겠습니다.

making_guestbook_using_rails_16

rake 라는 명령을 사용하여 데이터베이스 마이그레이션을 진행하게 되는데 Tools – Run Rake Task…메뉴를 통해 실행할 수 있습니다. 단축키는 Option + R 입니다.

making_guestbook_using_rails_17

마이그레이션 시점을 선택할 수 있습니다. 일단 하나밖에 없군요. 그냥 latest migration을 선택하도록 하겠습니다.

making_guestbook_using_rails_14_2

이번에는 컨트롤러를 만들어보았습니다. 여기서 주목할 점은 컨트롤러의 이름이 복수형이라는것 그리고 액션에 7개를 추가하였습니다. 이 7개의 액션은 외울필요가 있습니다. 이후에 나올 라우팅 설정에서 리소스라는것과 연결되게 됩니다. 각각은 다음을 담당하게 됩니다.

  • index : 방명록의 모든 글을 보여줍니다.
  • new : 방명록에 새로운 글을 작성하는 HTML폼을 보여줍니다.
  • create : 방명록에 새로운글을 추가합니다. 데이터베이스에 INSERT 하는 작업을 수행합니다.
  • show : 방명록에 작성된 글중 하나의 특정한 글을 보여줍니다.
  • edit : 방명록에 작성된 글 중 하나의 특정한 글을 수정하는 HTML폼을 보여줍니다.
  • update : 특정한 글의 내용을 수정합니다. 데이터베이스에 UPDATE 하는 작업을 수행합니다.
  • destroy : 방명록에 작성된 글 중 하나의 특정한 글을 삭제합니다.

making_guestbook_using_rails_18

여기에 보이는 버튼들을 이용하여 서버를 종료하거나 재시작할 수 있습니다. 재시작하기 전에 라우팅 설정을 좀 살펴보겠습니다. 라우팅 설정파일은 config/routes.rb 파일을 참고하시면 됩니다. 여기서 외부의 어떤 요청을 어떤 컨트롤러에 연결해줄것인가에 대한 정의를 하게 됩니다.

making_guestbook_using_rails_19

음… IntelliJ께서 친절하게 자동으로 뭔가를 추가해주셨네요. 밑에 post/*들은 테스트로 해봤다가 남아있는 잔재입니다; 위의 내용을 모두 삭제하고 다음으로 변경합시다.

Guestbook::Application.routes.draw do
  resources "posts"
end

이제 서버를 새시작하고 http://localhost:3000/posts 에 접속해 봅시다.

making_guestbook_using_rails_20

/posts 로의 요청이 자연스럽게 PostsController의 index 액션을 타고 결과적으로 index 뷰가 출력되었습니다. 저 resources 설정이 자동으로 필요한 라우트 설정을 추가해 줍니다. 이를 확인해 보려면 rake routes를 실행해 보는 방법이 있습니다. Option + R 을 눌러 rake 실행창을 열고 routes를 실행해 봅시다.

   Prefix Verb   URI Pattern               Controller#Action
    posts GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
 new_post GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
     post GET    /posts/:id(.:format)      posts#show
          PATCH  /posts/:id(.:format)      posts#update
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy

Process finished with exit code 0

이것을 천천히 봐보시면 알 수 있지만 /posts/* 패스를 이용하여 기존에 생성했던 7개의 메소드에 연결해주는것을 볼 수 있습니다. 위의 내용을 해석해 보면 다음을 알 수 있습니다.

  • GET /posts 를 요청하면 방명록에 작성된 모든 글을 보여준다. (디비 SELECT)
  • POST /posts 를 요청하면 방명록에 새로은 글을 추가한다. (디비 INSERT)
  • GET /posts/new 를 요청하면 방명록에 새로운 글을 작성할 수 있는 HTML 폼을 보여준다.
  • GET /posts/:id/edit 를 요청하면 방명록에 기존에 작성된 글을 수정할 수 있는 HTML 폼을 보여준다.
  • PATCH 또는 PUT /posts/:id 를 요청하면 방명록에 기존에 작성된 글의 내용을 수정한다. (디비 UPDATE)
  • DELETE /posts/:id 를 요청하면 방명록에 기존에 작성된 글을 삭제한다. (디비 DELETE)

여기서 재미있는 점이 한가지 있는데 Prefix에 있는 값들을 레일즈안에서 마치 메소드처럼 호출하여 사용할 수 있습니다. (posts_path, new_post_path 등.. 뒤에서 설명하겠습니다) 이제 위의 기능들이 하나하나 동작하도록 고쳐보겠습니다.

일단 방명록이라고 하면 대체적으로 상단에 글쓰기 폼이 있고 그 밑으로 기존에 작성된 글들이 리스트되어 보여지는 형태입니다. 그러므로 이 프로젝트에서는 GET /posts/new 페이지는 없어도 괜찮을지 모르겠습니다. 그러면 먼저 GET /posts 에 글쓰기 폼을 추가해 보겠습니다. app/views/posts/index.html.erb의 내용을 다음과 같이 수정하였습니다. 레일즈에서 제공하는 Form Helper를 사용하였습니다. HTML 쌩코딩을 하고싶었지만 일반 HTML폼으로는 GET/POST이외에는 구현하기 어렵기 때문에 이것을 사용하는것이 좋을것 같습니다.

<h1>Guestbook List</h1>
<%=form_for :post, url: posts_path, method: :post do |f| %>
    Name : <%=f.text_field :name  %><br>
    Email : <%=f.text_field :email  %><br>
    Password : <%=f.password_field :password  %><br>
    <%=f.text_area :content  %>
    <%=f.submit %>
<% end %>

그리고 http://localhost:3000/posts에 들어가면 다음과 같은 화면을 볼 수 있습니다.

making_guestbook_using_rails_21

새로운 글 작성에 필요한 폼이 만들어졌습니다. 위에서 확인했었던 routes 값과 비교해 보면 POST 메소드로 posts_path에 요청을 날리게 되어있습니다.(form의 action과 method값 확인) 여기서의 posts는 routes 결과 첫번째 줄에 정의된 값입니다. 거기 정의되어있는 URI Pattern값을 반환하게 됩니다. 즉 /posts 를 반환하게 됩니다.

rake routes의 결과에서 가장 앞단에 있는 Prefix의 값은 URI Pattern에 정의되어있는 값과 매칭됩니다. 하지만 Prefix라는 명칭에서 알 수 있듯이 접두사로 쓰이게 되며 뒤에 _path 또는 _url을 붙여서 사용합니다. _path를 붙인 경우 주소의 패스값을 반환하게 되고 _url을 붙이게 되면 도메인, 포트등의 모든 주소를 붙인값을 반환하게 됩니다.

<%=posts_path %> 라고 하였으니 도메인이나 포트 정보가 제외된 형태 즉, /posts 를 반환합니다.

폼의 제출 버튼을 누르면 POST /posts 를 수행하게 될테니 routes 정보를 볼때 posts#create가 실행될것이라는것을 알 수 있습니다. create 액션을 만들어보겠습니다.

def create
  post = Post.new
  post.name = params[:post][:name]
  post.email = params[:post][:email]
  post.password = params[:post][:password]
  post.content = params[:post][:content]
  post.save
  redirect_to posts_path
end

POST로 넘어온 파라미터로 그대로 넘기는것이 가능한 이유는 HTML폼의 필드들의 name의 값과 디비(모델)의 필드명이 동일하기때문에 가능한 부분입니다.이제 http://localhost:3000/posts 에 진입하여 폼을 채우고 “제출” 버튼을 눌러봅시다.

아무런 오류없이 다시 글쓰기 폼이 보이는것을 확인할 수 있습니다. 리다이렉트가 잘 되는군요. 이제 저장된 결과를 출력해 봅시다. 먼저 PostsController (app/controllers에 존재)에 index 액션을 수정합니다.

def index
  @posts = Post.all
end

posts/index.html.erb 뷰에는 form 밑에 다음을 추가해 줍니다.

<% @posts.each do |post| %>
<div>
    <p><%=post.name%> (<%=post.email%>)</p>
    <p><%=post.content%></p>
</div>
<% end %>

이제 수정된 결과를 확인하러 가봅시다.

making_guestbook_using_rails_23 making_guestbook_using_rails_24

작성한 글이 잘 출력되어 보여지는군요. 이제 수정과 삭제 버튼을 만들어 보겠습니다. 위의 erb내용을 다음과 같이 좀 더 업데이트 해봅시다.

<% @posts.each do |post| %>
<div>
    <p>
        <%=post.id%>
        <%=link_to "수정", edit_post_path(post.id) %>
        <%=link_to "삭제", post, :method => :delete %></p>
    <p><%=post.name%> (<%=post.email%>)</p>
    <p><%=post.content%></p>
</div>
<p></p>
<% end %>

posts/edit.html.erb 뷰파일을 다음과 같이 수정합니다.

<h1>Guestbook Edit</h1>
<%=form_for :post, url: post_path(@post), method: :patch do |f| %>
    Name : <%=f.text_field :name  %><br>
    Email : <%=f.text_field :email  %><br>
    Password : <%=f.password_field :password  %><br>
    <%=f.text_area :content  %>
    <%=f.submit %>
<% end %>

PostsController의 edit, update, destroy 액션의 내용을 추가합니다.

def edit
  @post = Post.find(params[:id])
end

def update
  post = Post.find(params[:id])
  post.name = params[:post][:name]
  post.email = params[:post][:email]
  post.password = params[:post][:password]
  post.content = params[:post][:content]
  post.save
  redirect_to posts_path
end

def destroy
  post = Post.find(params[:id])
  post.destroy
  redirect_to posts_path
end

이제 기본적으로 새로운글을 추가, 수정, 삭제가 가능한 방명록(이라고 부르긴 힘들겠지만)을 만들어 보았습니다. 비밀번호 대조를 통해서 수정시 뭔가 체크를 하는 기능을 구현하고자 password를 만들었지만 그부분은 패스하겠습니다^^;