-
[루비온레일즈] MVC 패턴(업데이트, 삭제 기능)Ruby on Rails 2021. 3. 7. 00:53
이전 포스팅에서 MVC 패턴을 활용해 CR 기능을 구현했습니다.
이제 CRUD 중 남은 Update(수정)와 Destroy(삭제) 기능을 만들어보겠습니다.
1. Destroy 기능
삭제 기능도 create나 index와 마찬가지로 컨트롤러, 라우트가 필요합니다.
하지만, 보통 웹사이트에서 게시물을 삭제하면 이전 페이지로 돌아가거나 전체 목록으로 돌아가는 것처럼 삭제 기능의 뷰 파일은 필요없는 경우가 있습니다.
그래서 삭제 기능은 뷰 파일 없이 컨트롤러에서 Destroy 액션을 만들어주고, 라우트를 설정하고, index 에서 삭제 링크를 달아주는 것으로 만들겠습니다.
delete 액션 만들기
컨트롤러는 이전과 마찬가지로 posts_controller.rb 라는 컨트롤러 파일에 destroy 액션을 추가하면됩니다.
그리고, 아래 코드를 넣어줍니다.
def destroy
@post = Post.find(params[:post_id])
@post.destroy
redirect_to '/posts/index'
end이 코드는 우선 @post, 즉 각 게시물의 params 안의 게시물의 id(post_id)를 찾아서(find), 삭제하고, index 페이지로 돌아가라는 의미입니다.
이때, 파람스에서 post_id 는 각 게시물의 id 값을 의미하며, 이 id 를 찾는 이유는 각 게시물 마다 삭제가 필요하기 때문입니다.
그리고 id 값은 게시물이 생성되면 자동으로 생성되는 값으로 따로 만들어주지 않아도 됩니다.
index 페이지에서 삭제 링크 만들기
다음 과정은 전체 목록 페이지인 Index에서 각 게시물 옆에 삭제 링크를 만들어야 합니다.
저번 포스팅에서 each do~end 구문을 사용해 각 게시물의 제목과 내용을 불러왔듯이, do~end 사이에 삭제 링크를 넣어주겠습니다.
<a href='/posts/destroy/<%=x.id %>'>삭제</a>
이 코드의 <a> 태그는 파일 등을 연결해주는 링크인데요, href 속성과 함께 사용하면 주소 링크를 걸 수 있습니다.
형식에 맞춰 우리가 연결할 /posts/destroy/<%=x.id %>를 입력하는데 이때, 맨 뒤에 루비 코드는 각 게시물의 id 를 의미합니다.
이 코드를 통해 각 게시물들은 each do~end 사이에서 제목, 내용, 그리고 id 값에 따른 삭제 버튼까지 보여주게 됩니다.
그리고 <a>태그 사이에 삭제 라고 적어주고 태그를 닫아줍니다.
라우트 설정하기
이제 액션과 뷰를 만들었으니 이를 연결할 라우트를 설정하겠습니다.
/config/routes.rb 파일에 들어가 아래 코드를 넣어줍니다.
get 'posts/destroy/:post_id' => 'posts#destroy'
이 코드는 이전의 라우트들과 조금 달라보이는데요,
각 게시물들의 삭제 기능을 만들기 위해 post_id 값을 액션과 뷰 파일에 넣었기 때문에 이를 라우트에도 넣어주고,
=> 'posts#destroy' 는 앞의 경로를 통해 posts 컨트롤러의 destroy 액션으로 보내라는 의미입니다.
이제 삭제 기능이 잘 작동하는지 확인하겠습니다.
삭제 기능이 잘 작동하는 것을 볼 수 있습니다.
그런데 index 페이지에 새 글 쓰기 링크가 없어서 불편하니 지금 새 글 쓰기 버튼을 만들어주겠습니다.
새 글 쓰기는 앞에서 new 페이지에서 만들었습니다. 따라서, index 페이지와 new 페이지를 연결하는 버튼을 만들면 됩니다.
index.html.erb 파일에 가서 새 글 쓰기는 각 게시물들에게 요청하는 것이 아니기 때문에 each do~end 구문 밖에 코드를 작성해야 합니다.
<button>
<%=link_to '새 글 쓰기', '/posts/new' %>
</button><button> 태그는 버튼을 만들 때, 사용하는 코드이고 <%=link_to %> 태그도 <a href> 태그와 마찬가지로 링크를 걸어주는 태그입니다.
둘의 차이점은 <a href> 태그는 html의 태그이고, <%=link_to %> 태그는 루비 코드로 이루어진 태그로 좀 더 간편하게 코드를 작성할 수 있습니다.
형식은 다음과 같습니다.
<%= link_to '링크 이름', 'url' %>
이렇게 새 글 쓰기 버튼까지 만들었습니다.
이제 이어서 Update 기능을 만들어보겠습니다!
2. Update 기능
잠깐 수정 기능이 어떻게 이루어지는지 생각해보겠습니다.
제가 지금 이 포스팅을 작성하고 나서 오타를 발견하고 수정하려면 어떻게 해야 할까요??
우선 이 포스팅, 즉 특정 게시물의 수정하기 버튼을 눌러 이전에 썼던 내용을 불러오고 내용을 수정합니다.
다음 저장하기 버튼을 눌러서 그 게시물의 수정된 내용을 저장해야 합니다.
따라서, 수정하기는 다음 두 단계로 구성되어 있습니다. '이전 글 불러와서 작성하기'와 '저장하기' 입니다.
그래서 컨트롤러에서 불러오기와 저장하기에 해당하는 두 가지 액션이 필요합니다.
또한, 특정 게시물을 불러오고 저장해야 하기 때문에 여기에도 post_id 값을 모두 넣어주어야 합니다.
저는 불러오기와 저장하기를 각각 edit, update으로 컨트롤러의 액션, 라우트, 뷰 파일을 만들어주겠습니다.
edit 액션, 뷰, 라우트 만들기
우선 edit 부터 해보겠습니다. 컨트롤러에서 edit 액션을 만들고, 아래 코드를 삽입해 이전 글을 불러옵니다.
@post = Post.find(params[:post_id])
이 코드는 각 게시물들에 담긴 파람스(정보들)에서 post_id 값에 따라 특정 게시물을 불러오라는 의미입니다.
그리고 액션을 만들었으니 불러온 게시물을 보여주는 뷰를 만들겠습니다.
이전처럼 edit.html.erb 파일을 만들고 코드를 작성하기 전에 잠시 생각을 해보면, 불러오기의 화면 출력 양식은 새 글 작성 양식과 동일합니다. 새 글 작성하는 양식에 이전 글의 post_id 를 넣어주면 이전에 입력한 데이터를 받아올 수 있을 것입니다.
따라서, new.html.erb 의 양식을 그대로 복붙한 후, 아래처럼 코드를 수정하여 post_id 값을 넣어줍니다.
수정한 부분을 짚어보면, 첫번째 줄의 이를 수행할 액션을 업데이트로 지정하고 게시물의 id 값을 넣었습니다.
그리고, 이전에 작성한 제목과 내용을 불러와야 하기 때문에 value 속성으로 각 게시물의 제목과 내용을 불러오도록 했습니다.
이전에 new.html.erb 파일을 작성할 때 input 태그를 활용해 사용자에게 데이터를 입력받을 폼을 만들었는데요,
이때 input 태그 안에 value 속성을 이용하면 안에 내용을 채워줄 수 있습니다.
내용 부분의 textarea 태그에 값을 넣어줄 때는 <textarea></textarea> 태그 사이에 입력해줍니다.
이제 라우트를 만들어주겠습니다.
이전 게시물을 불러와야 하기 때문에 destroy와 같은 형태로 코드를 작성해줍니다.
다음은 index 에서 각 게시물마다 수정하기 링크를 달아줄 차례입니다.
이전에 삭제 링크를 만드는 방법과 같습니다.
do~end 사이에 <a> 태그에 href 속성으로 destroy가 아니라 edit 즉 불러오기 링크를 걸고, 각 id에 맞게 불러오도록 합니다.
이제 edit(불러오기)가 정상적으로 작동하는 지 확인해보겠습니다.
이렇게 index 페이지의 수정 링크가 잘 작동하고, edit 페이지에서 이전 내용을 잘 가져오는 것을 확인할 수 있습니다.
계속해서 수정한 내용 저장하기, 즉 update 기능을 만들겠습니다.
update 액션, 뷰, 라우트 만들기
posts_controller.rb 에 가서 update 액션을 만듭니다.
어떻게 만들어야 할까 생각해보니, new-create 기능이 edit-update 와 대응되는 기능이라는 생각이 들었습니다.
단지 차이점은 edit-update에서는 이전 글을 불러와야 하기 때문에 id 값을 넣어주는 것입니다.
그래서 edit 액션, 뷰를 만들 때 new에서 코드를 복붙해서 필요한 부분만 수정한 것처럼, update 액션을 만드는 경우에도 이전의 create의 코드를 가져와 수정하겠습니다.
이 코드는 업데이트 액션에서는 게시물의 id 값을 찾아서, 제목과 내용을 저장하고 index 페이지로 가라는 뜻입니다. 결국, create 액션과 차이는 단지 id 값입니다.
이렇게 컨트롤러 파일을 열어서 보면, 방금 얘기했다싶이 new-create , edit-update 가 짝을 이루며 대응되네요! 둘다 데이터를 입력하고 저장하는 기능이라는 공통점이 있기 때문입니다.
하지만, edit-update 는 계속 말했듯이 이전에 작성된 특정 게시물을 불러오고 저장해야 하기 때문에 id 값이 들어가는 반면, new-create는 기존에 없었던 새로운 게시물을 작성하고 저장하기 때문에 id 값을 찾는 코드가 들어가지 않습니다.
각각의 액션을 비교하는 것은 여기까지 하고 계속해서 update의 뷰를 만들어보려고 했는데 생각해보니 create의 뷰가 없듯이, update도 뷰가 필요 없습니다.
내용을 수정하는 폼은 이미 edit에서 만들었고, update 액션은 create 액션처럼 수정한 내용을 저장하는 기능이기 때문에 따로 화면에 출력할 것이 없습니다.
update 라우트도 create 와 마찬가지로 get 방식이 아니라 post 방식으로 데이터를 전달하고, id 값을 넣어줍니다.
이제 수정 후 저장하기 기능까지 잘 구현되는지 확인해보겠습니다!
기존에 작성한 첫번째 게시물의 제목과 내용을 수정하고 제출 버튼을 눌렀더니, index 페이지로 가면서 수정한 내용이 잘 저장되었습니다!!😁😁
이렇게 MVC 패턴을 활용해 CRUD를 구현해보았는데요, 다음 포스팅부터는 지금까지 하나하나 만들어낸 CRUD 기능을 한번에 만들어주는 Rails 의 scaffold를 만들어보고 그 안에 담긴 코드들을 살펴보겠습니다!
'Ruby on Rails' 카테고리의 다른 글
[루비온레일즈] 댓글 기능 구현하기 (부모-자식 관계) (0) 2021.03.11 [루비온레일즈] Scaffold 생성하고 뜯어보기 (0) 2021.03.11 [루비온레일즈] MVC 패턴(모델, CR 기능 만들기 2) (0) 2021.03.07 [루비온레일즈] MVC 패턴(모델, CR기능 만들기1) (0) 2021.03.05 [루비온레일즈] MVC 패턴(뷰, 컨트롤러, 라우트) (0) 2021.03.05