Rails 5 on aws c9
N6. Post 수정과 삭제
컴퍼
2020. 7. 5. 16:45
이번엔 수정과 삭제를 구현해보자.
<div class="container">
<div class="row">
<!-- 작은 사이즈에선 12개로 꽉차고, 중간사이즈부터는 4를 차지-->
<div class="col s12 m4">
<div class="card">
<div class="card-image">
<!-- 일단은 샘플 이미지 -->
<img src="http://materializecss.com/images/office.jpg"/>
</div>
<div class="card-content">
<div class="card-title">
<!-- 로그인했다면, 현재 유저의 이름이 뜬다 -->
<%= current_user.name %>
</div>
<p>
이메일 : <%= current_user.email %>
</p>
<p>
<!-- posts_count 는 컨트롤러에서 작성을 해줘야 뜬다 -->
올린 글 개수 : <%= @posts_count %>
</p>
<!--헬퍼를 이용해 포스트 작성하기로 이동-->
<%= link_to new_post_path do %>
<button class="btn">글 쓰기</button>
<% end %>
</div>
</div>
</div>
<!-- 작은 사이즈에선 12개로 꽉차고, 중간사이즈부터는 8를 차지-->
<div class="col s12 m8">
<!-- @posts : DB에 저장된 모든 포스트를 컨트롤러에서 역순으로 보내줌-->
<!-- 이를 하나하나 뽑아 임시변수 post로 받음-->
<% @posts.each do |post| %>
<div class="card">
<div class="card-content">
<!-- 해당포스트의 작성자의 이름을 출력 -->
<span class="card-title"><%= post.user.name %></span>
<span><%=post.created_at %></span>
<p><%= post.content %></p>
</div>
<div class="card-action">
<a href="#">좋아요</a>
<% if current_user.id == post.user_id %>
<%= link_to "수정", edit_post_path(post), class: "right" %>
<% end %>
<a href="#">댓글 달기</a>
</div>
</div>
<% end %>
</div>
</div>
</div>
views/posts/edit.html.erb 추가 (edit 에는 내용이 차 있어야 한다)
<div class="container">
<div class="row">
<div class="card col s12">
<div class="card-content">
<div class="card-title">
수정하기
</div>
<!-- 라우트를 확인해 업데이트 액션으로 이어지게 해야함-->
<!-- Prefix 가 다름! posts_path 대신 post_path-->
<!-- 해당 개시글의 번호를 params id 로 받을 수 있음-->
<!-- 컨트롤러에 @post = Post.find_by(id: params[:id]) 추가-->
<%= form_tag post_path(@post), method: "patch" do %>
<input type="hidden" name="id" value="<%= @post.id %>"
<div class="input-field">
<%=text_area_tag :content, @post.content, class: "materialize-textarea", placeholder: "무슨 생각을 하고 있나요?" %>
</div>
<div class="input-field">
<%= button_tag "수정하기", class: "btn" %>
</div>
<% end %>
</div>
</div>
</div>
</div>
class PostsController < ApplicationController
before_action :authenticate_user!
def index
# views/posts/index.html.erb 에서 볼 수 있음
# @posts변수에 모든 포스트를 created_at 기준 역순으로 정렬한걸 할당
@posts = Post.all.order('created_at desc')
# @posts_count 변수에 현재 로그인한 유저의 포스트 수를 할당
@posts_count = current_user.posts.length
end
def new
end
def create
#new_post라는 임시변수를 만들고
#Post 모델에서 새로운 객체를 생성해서
#user_id: 는 현재 로그인한 사람의 id를 넣고
#내용은 파리미터로 온 content를 넣어서 저장해주겠다.
new_post = Post.new(user_id: current_user.id, content: params[:content])
if new_post.save
redirect_to root_path
else
redirect_to new_post_path
end
end
def edit
#edit.html.erb에서 @post 사용할 수 있게 함
@post = Post.find_by(id: params[:id])
end
def update
#데이터베이스에서 수정할 글을 찾으려면 params[:id] 가 필요
#<input type="hidden" name="id" value="<%= @post.id %>" 를 edit.html.erb 에 추가
@post = Post.find_by(id: params[:id])
#수정권한이 없으면 돌려보냄
redirect_to root_path if @post.user_id != current_user.id
@post.content = params[:content]
if @post.save
redirect_to root_path
else
render :edit
end
end
end
여기까지 했을 때 내용에 줄바꿈이 적용이 안됨
views/posts/index.html.erb 수정
<div class="container">
...
<div class="col s12 m8">
...
**<p class="pre-line"><%= post.content %></p>**
...
</div>
...
</div>
assets/stylesheets/posts.scss 수정
// Place all the styles related to the Posts controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.pre-line {
white-space: pre-line;
}
삭제를 구현하자
<div class="container">
...
<% if current_user.id == post.user_id %>
<%= link_to "삭제", post_path(post), method:"delete", class: "right" %>
<%= link_to "수정", edit_post_path(post), class: "right" %>
<% end %>
...
</div>
class PostsController < ApplicationController
before_action :authenticate_user!
...
def destroy
@post = Post.find_by(id: params[:id])
#수정권한이 없으면 돌려보냄
redirect_to root_path if @post.user_id != current_user.id
@post.destroy
redirect_to root_path
end
end
이제 코드를 효율적으로 짜보자
글을 찾아오고 권한채크하는게
update 하고 destroy 할 때 권한채크를 각각 구현했다.
edit 페이지를 권한이 없으면 아예 안띄워주는것도 구현하고싶다.
하는 상황이 올 수 있다.
이걸 프라이빗 메소드로 따로 빼자
class PostsController < ApplicationController
before_action :authenticate_user!
before_action :check_ownership, only: [:edit, :update, :destroy]
def index
# views/posts/index.html.erb 에서 볼 수 있음
# @posts변수에 모든 포스트를 created_at 기준 역순으로 정렬한걸 할당
@posts = Post.all.order('created_at desc')
# @posts_count 변수에 현재 로그인한 유저의 포스트 수를 할당
@posts_count = current_user.posts.length
end
def new
end
def create
#new_post라는 임시변수를 만들고
#Post 모델에서 새로운 객체를 생성해서
#user_id: 는 현재 로그인한 사람의 id를 넣고
#내용은 파리미터로 온 content를 넣어서 저장해주겠다.
new_post = Post.new(user_id: current_user.id, content: params[:content])
if new_post.save
redirect_to root_path
else
redirect_to new_post_path
end
end
def edit
end
def update
@post.content = params[:content]
if @post.save
redirect_to root_path
else
render :edit
end
end
def destroy
@post.destroy
redirect_to root_path
end
private
def check_ownership
#edit.html.erb에서 @post 사용할 수 있게 함
#데이터베이스에서 처리할 글을 찾으려면 params[:id] 가 필요
#<input type="hidden" name="id" value="<%= @post.id %>" 를 edit.html.erb 에 추가
@post = Post.find_by(id: params[:id])
#수정권한이 없으면 돌려보냄
redirect_to root_path if @post.user_id != current_user.id
end
end