ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [루비온레일즈] Scaffold 생성하고 뜯어보기
    Ruby on Rails 2021. 3. 11. 12:26

    이전 포스팅에서 MVC패턴을 활용해 CRUD 기능을 구현해서 게시판을 만들어보았습니다.

     

    오늘은 이 CRUD 기능을 하나하나 만드는 것이 아니라 한번에 컨트롤러, 뷰, 라우트, 모델 등 모든 기능을 한번에 만들어주는 Scaffold를 사용해서 CRUD를 만들어보겠습니다.


    1. Scaffold 생성하기

     

    RubyMine에서 스캐폴드를 만드는 방법은 다음과 같습니다.

    상단 Tools 메뉴 - Run Rails Generator - rails g scaffold 를 입력해 스캐폴드 생성창을 실행합니다.

    이 창에서 모델이름, 필드명:타입을 작성합니다.

    저는 Board title:string content:text로 해보겠습니다.

    이 방법은 터미널에서 다음 명령어를 활용해 동일하게 스캐폴드를 만들수 있습니다.

    rails g scaffold board title:string content:text

     

    스캐폴드를 만들면, 아래 이미지와 같이 여러 파일들이 생성됩니다.


    2. Scaffold 살펴보기

     

    이제 이 파일을들 천천히 살펴보겠습니다.

     

    마이그레이션, 모델 파일(Migration, board.rb)

    맨 위에는 마이그레이션 파일과, 모델 파일 그리고 테스트 파일이 생성된 것을 확인할 수 있습니다.

    우선, 마이그레이션 파일에 들어가보면 전에 우리가 모델을 만들었던 것과 같은 형식으로 마이그레이션 파일이 만들어진 것을 확인할 수 있습니다.

    그 다음, 이렇게 모델 파일인 board.rb도 생성되었구요.

     

    라우트(config/routes.rb)

    그 아래에는 라우트가 설정되는데요, 전에는 get 'posts/index' 형식으로 라우트를 일일이 설정해주었다면 scaffold를 만들면 resources :boards 라는 코드가 생성됩니다.

     

    이 코드에는 이전에 제가 하나하나 작성했던 index, show, new, create, edit, update, destroy와 같은 CRUD 액션과 관련된 라우트들이 모두 담겨 있어서 따로 라우트를 설정하지 않아도 됩니다.

     

    컨트롤러(boards_controller.rb)

    그 다음 boards_controller.rb인 컨트롤러 파일을 살펴보면, 이전 포스팅에서 작성한 코드들과 조금 다른 코드들이 들어있습니다.

    scaffold로 생성된 컨트롤러
    scaffold로 생성된 컨트롤러

    아래 이미지는 이전 포스팅에서 scaffold 없이 작성했던 Post 컨트롤러의 코드입니다.

    scaffold 없이 작성한 컨트롤러 코드

    우선, 맨 위에 before_action 으로 시작하는 코드 한 줄부터 다른데요, 이는 이 코드의 의미는 컨트롤러에서 액션을 수행하기 전에 오직 show,edit,update,destroy에 관해서 set_board를 수행하라는 의미입니다.

    그리고 여기서 set_board는 무엇인가 찾아보니, 맨 아래에 내려가보면 아래 private 메소드 안에 set_board 메소드가 정의되어 있습니다.

    그리고 안에 코드를 보면 @board 인스턴스변수는 params에서 id 값을 집어넣은 것이라는 뜻으로 쉽게 말해 각각의 board를 만들 때 id 값을 저장한다는 의미입니다.

    결국, show, edit, update, destroy 액션 시 스캐폴드 없이 만들었을 때는 id 를 하나하나 넣어준다는 코드를 작성해야 하지만, scaffold를 이용하면 액션(데이터 처리)을 하기 전에 미리 알아서 id 값을 넣어주는 것입니다.

     

    또 컨트롤러에서 다른 점을 살펴보니 create 액션에 이런 차이점이 있습니다.

    scaffold로 만든 컨트롤러 안의 create 액션
    scaffold를 사용하지 않은 create 액션

    우선, 스캐폴드 없이 만들었을 때는 @post는 새로만드는 글이라는 것과, 제목, 내용에 각각의 파람스를 담아주고 저장을 했습니다.

    하지만, 스캐폴드로 만들면 각각의 제목, 내용을 담아줄 필요 없이 board_params를 통해 스캐폴드가 알아서 제목과 내용 등 새 글 작성 시 필요한 파람스를 전달하고 있습니다.

     

    그리고 그 하단에 respond_to do |foramt| ~ end 사이에 복잡해 보이는 if 조건문이 있는데요,

    이 코드들을 살펴보면 해당 포맷으로 보여주라는 의미인데 그 안에 if @board.save 즉 만약 저장이 되면 포맷이 html이면 @board로 돌아가면서 "Board was successfully created." 라는 notice를 띄우고,

    그 포맷에 json이면 show를 불러오라는 의미입니다. json은 html처럼 화면 상에 보여주는 방식이라고 알고 있으면 될 것 같습니다.

     

    그리고 계속해서 else 는 저장이 되지 않는다면, html 포맷에서는 render :new 즉, new 를 보여주라는 의미이고,  json 포맷에서는 @board.errors 에러를 표시하라는 의미입니다.

     

    그리고 다시 바로 위로 올라가서 def create 아랫줄에 @board = Board.new(board_params)의 이 board_params 가 어디 있는지 살펴보면, 맨 아래쪽 private 메소드 안에 board_params 메소드가 정의되어 있습니다.

    이 코드를 살펴보면, board에 대해 params를 요청하고 그 중, title과 content 만들 허용한다 즉, board의 params에서 title 과 content만 보내겠다는 뜻으로 이렇게 정의된 board_params를 통해 create 액션에서 @board = Board.new(board_params) 한줄로 세 줄을 대체할 수 있는 것입니다.

     

    create 말고도 update에도 (board_params)가 붙어있는데요,

    나중에 필드가 title, content 말고도 여러 개를 추가해야 한다거나, 다른 모델과의 관계를 설정하는 등 수정사항이 있을 때, 그와 관련된 모든 코드들을 찾아서 수정하지 않고, private 안에 board_params를 정해줌으로써 필요한 params만 받아올 수 있도록 해서 훨씬 편리하게 코딩을 할 수 있습니다!

     

    뷰 파일

     

    다음으로 살펴볼 scaffold로 생성된 파일은 뷰 파일들 입니다.

    sacffold는 이렇게 html.erb 즉 뷰 파일들도 자동으로 생성해줍니다.

    먼저 index.html.erb 파일을 살펴보겠습니다.

    맨 윗줄에는 <p> 태그 안에 아까 컨트롤러에서 봤던 notice를 넣어두었고, 다음 <h1>태그로 사이트 이름, 아래에 <table> 태그 안에 <thead> 태그로 Title, Content 라는 텍스트를 넣어주었고 그 아래 <tbody>에 작성된 게시물들의 제목과 내용 데이터가 화면에 나타나도록 each.do end 로 코드를 작성하고 show, edit, destroy 링크를 넣어두었습니다.

    그리고 마지막으로 새 글을 작성할 수 있도록 new 링크가 작성되어 있네요.

     

    테이블 바디 안의 코드의 의미를 보면,

    각 게시물들(@boards)은 각각 다음과 같이 해라. <%= board.title %>, <%= board.content %> 즉 각각의 제목과 내용을 보여줘라. 

     

    그리고, <%= link_to 'Show', board %>는 Show를 누르면 board로 보내라.

     

    <%= link_to 'Edit', edit_board_path(board) %> 는 Edit을 누르면 edit_board_path(board)로 보내라. 는 뜻인데 여기서 edit_board_path(board)는 각각의 게시물 경로를 의미합니다.

    즉, 이전에 MVC 로 업데이트 기능을 만들때, 특정 게시물을 불러와서 수정 후 저장해야 한다고 했는데 이와 같은 이유로 각각의 게시물 경로로 보내는 것입니다.

     

    <%= link_to 'Destroy', board, method: :delete, data: { confirm: 'Are you sure?' } %> 는 Destory를 누르면 board로 보내는데, method가 delete이므로 이 게시물은 삭제가 됩니다. 그리고 삭제 되기 전에 Are you sure? 이라는 메세지를 띄웁니다.

     

    <%= link_to %> 는 루비 코드를 활용해 링크를 거는 태그인데요.

    <%= link_to '링크 이름', url, method: :전달방식 %> 

    이런 형식으로 작성합니다. 그리고 url에는 xxx_path를 활용해도 되며, method를 지정해줄 때에 get 방식은 아무런 말을 해주지 않아도 method를 get 방식으로 인식하고 전달합니다.

     

    그래서 위 코드에서도 get방식인 show 와 edit에는 method가 정의되지 않은 반면, delete 방식인 Destroy 링크에는 method를 지정해준 것입니다.

     

    다음은 new.html.erb 과 edit.html.erb 즉, new와 edit의 뷰파일을 보겠습니다.

    스캐폴드를 사용하지 않고 만들었던 뷰 파일과 비교해보면 상당히 단순한 코드로 작성되어 있는데요

    가장 큰 차이점은 form을 직접 작성하지 않았다는 것입니다.

     

    우선 코드의 의미를 보면, 맨 윗줄에 New Board라는 새 글을 작성하는 페이지라는 텍스트가 있고 그 아래 render로 form을 불러오고

    link_to를 이용해서 Back, board_path(index 페이지)로 뒤로가기 링크를 걸어주고 있습니다.

    scaffold로 만든 new.html.erb
    scaffold 없이 만든 new.html.erb


    scaffold로 만든 edit.html.erb
    scaffold 없이 만든 edit.html.erb

    그럼 'form'은 어디에서 불러오는 건지 찾아보면, BoardsController/Partials/_form.html.erb 에 해당 폼이 작성되어 있습니다.

    결국, new 나 edit 모두 해당 form을 불러와서 뷰로 보여주는 것입니다.

    다시말해 render로 form을 불러오기 위해서는 partial 에 _form.html.erb 파일이 존재해야한다는 뜻인데, 이 폼 파일을 직접 만들어줄 경우에는 form 앞에 _(언더바)를 붙여주어야 한다는 규칙이 있습니다.

     

    그리고 _form.html.erb의 코드를 살펴보면, 1번의 폼 태그는 board model 과 관련된 form으로 form들은 아래 코드를 수행해라라는 뜻으로 2번 ~ 12번 if 조건문은 그 안에, 에러가 있으면 에러를 보여주고, 14번 ~ 26번은 <div> 태그 안에 <%= form.label :content %>, <%= form.text_field :title %> 이런 식으로 제목과 내용을 작성하는 폼을 만들고, 마지막에 제출 폼을 만든 것입니다.

     

    여기서 new와 edit의 차이점으로 edit은 이전에 작성된 글을 불러와야 한다는 점이 있었는데요,

    1번 줄의 form 태그에서 모델과 연결시켜주었고, new.html.erb와 edit.html.erb에서 <%= render 'form', board: @board %> 을 통해 form을 render헐(불러 올) 때 board: @board 이런 식으로 특정 게시물과 연결시켜주었기 때문에, new는 아무것도 없는 새 글 쓰기 폼으로, edit은 이전에 작성한 내용이 담긴 수정하는 폼으로 화면에 보여줄 수 있는 것입니다.

     

    그리고 show.html.erb에서도 이렇게 <%= link_to 'Edit', edit_board_path(@board) %> 링크 안에 @board로 특정 게시물을 불러올 수 있습니다.

    sacffold로 만든 show.html.erb

     

    이렇게 Scaffold로 만든 CRUD를 구성하는 파일들을 하나하나 살펴보았습니다.

    이제 실제로 웹페이지가 잘 작동하는 지 살펴보겠습니다.


    3. Scaffold로 만든 웹페이지

     

    이제 서버를 실행하고 http://localhost:3000/boards 로 접속해보겠습니다.

     

    접속했더니, 이렇게 마이그레이션 오류가 발생하는데요.

    Scaffold를 만들면 마이그레이션 파일과 모델 파일이 생성되기 때문에 rake db:migrate를 해줘야 하는데 깜빡했네요 ㅠㅠ..

    터미널에서 rake db:migrate 를 해주고, 정상적으로 처리되었으니 다시 서버를 열어보겠습니다.

     

    서버를 열어보니 아래 이미지들처럼 모든 CRUD 기능이 정상적으로 작동하는 것을 확인할 수 있습니다!

    index, new, create, show, edit, update, destroy 의 7가지 기능이 모두 잘 작동하네요😁😁


    오늘은 이렇게

    1. Scaffold로 순식간에 블로그 생성하고

    2. Scaffold로 만들어진 파일 안에 어떤 코드들이 있는지

    3. Scaffold 없이 만든 CRUD와는 어떤 차이점이 있는지 

    4. Scaffold로 만든 기능들이 잘 동작하는지

     

    살펴보았습니다!

     

    이런 Scaffold와 같은 편리한 기능들 때문에 Ruby on Rails로 쉽고 빠르게 웹사이트를 제작할 수 있는 것 같네요 ㅎㅎ

     

    다음 포스팅에서는 댓글 기능을 구현해보도록 하겠습니다~ 끝!

     

Designed by Tistory.