티스토리 뷰
오늘은 좋아요 기능 복습과 gem을 활용한 검색 기능에 대해 배워보도록 할게요!
M:N 모델 관계 다 기억하시나요?
좋아요 기능에 필요한 모델은 총 3개! Like, Post, User
이 세개의 모델은 각각 M:N 모델관계를 가지게 됩니다.
한 명의 User는 여러개의 Post를 작성할 수 있고 여러개의 Post에 대해 Like 버튼을 누를 수 있습니다.
한 개의 Post의 Like는 여러 명의 User들에게 눌릴 수 있습니다.
이 모델의 관계를 그림으로 나타내면 다음과 같습니다.
자 그럼 직접 만들어볼까요?
[모델 만들기]
scaffold를 활용해서 crud의 기본 토대를 만들어주세요.
1 2 3 | #bash창 rails g scaffold Post title:string body:tex | cs |
1 2 3 | #bash창 rails g model like post:references user:references | cs |
Devise gem을 설치해주세요.
1 2 3 | #Gemfile gem 'devise' | cs |
1 2 3 4 | #bash창 bundle install rails g devise:install | cs |
User모델도 만들어주세요.
이제 rake db:migrate 해주면 완성!
1 2 3 4 | #bash창 rails g devise user rake db:migrate | cs |
[모델 관계 설정]
app/models폴더를 확인해보면 우리가 사용할 3개의 모델이 만들어져있습니다.
이 모델들간의 관계를 설정해줍시다.
먼저 like모델을 확인해볼까요?
1 2 3 4 | #app/models/like.rb belongs_to :post belongs_to :user | cs |
이미 모델들관의 관계가 설정되어있는 것을 확인할 수 있습니다.
그렇다면 post모델을 설정해줄까요?
1 2 3 4 5 | #app/models/post.rb belongs_to :user has_many :likes has_many :liked_users, through: :likes, source: :user | cs |
마지막으로 user모델을 설정해주세요!
1 2 3 4 5 | #app/models/user.rb belongs_to :posts has_many :likes has_many :liked_posts, through: :likes, source: :post | cs |
"한 명의 User는 여러개의 Post를 작성할 수 있고 여러개의 Post에 대해 Like 버튼을 누를 수 있습니다."
[메소드 정의]
1 2 3 4 5 | #app/models/user.rb def is_like? (post) Like.find_by(user.id: self.id, post_id: post.id).present? end |
[컨트롤러 생성]
1 2 | #bash창 rails g controller likes | cs |
1 2 3 4 5 | #config/routes.rb root 'posts#index' post 'post/:post_id/like' => 'likes#like_toggle' get 'users/sign_out' | cs |
root ‘posts#index’ |
scaffold로 만들었던 index.erb를 메인화면으로!
|
post ‘post/:post_id/like’ => ’likes#like_toggle’ |
좋아요 기능을 수행할 컨트롤러 라우트 설정! |
get ‘users/sign_out’ |
user가 로그아웃 할 수 있도록 설정! |
여기서 잠깐!
우리가 만들고자 하는 화면의 모습을 잠시 확인 해볼까요?
views/posts/index.html.erb
views/posts/show.html.erb
scaffold를 통해 구현되지 않은 부분들은 전부 빨간색 네모로 만들었습니다.
우리는 이 빨간색 네모를 채워주려고합니다.
[View 설정]
먼저, show.html.erb 를 꾸며봅시다.
Like: N명이 좋아합니다.
[좋아요 버튼]
이 두가지 기능을 구현해 봅시다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #views/posts/show.html.erb <p> <strong>Like:</strong> <%= @post.likes.size %> 명이 좋아합니다. </p> <p> <% if current_user.is_like? (@post) %> <form action='/post/<%= @post.id%>/like' method='post'> <button> 좋아요 취소 </button> </form> <% else %> <form action='/post/<%= @post.id%>/like' method='post'> <button> 좋아요</button> </form> <% end %> </p> | cs |
현재 유저가 좋아요를 눌렀다면? 좋아요 취소 버튼 생성
현재 유저가 좋아요를 안눌렀다면? 좋아요 버튼 생성
[컨트롤러 채우기]
아까 like컨트롤러에 만들어준 like_toggle 메소드를 정의해줍시다.
1 2 3 4 5 6 7 8 9 10 11 12 | def like_toggle like = Like.find_by(user_id: current_user.id, post_id: params[:post_id]) if like.nil? Like.create(user_id: current_user.id, post_id: params[:post_id]) else like.destroy end redirect_to :back end | cs |
현재 유저의 id, 현재 보고있는 게시물의 id를 참조합니다.
만약, like가 nil일 경우, '좋아요' 반영, nil이 아닐 경우 '좋아요' 삭제
이제, view.html.erb 를 꾸며봅시다.
Like 목록을 추가하고 현재 몇 명의 User가 좋아요를 눌렀는지 확인할 수 있도록 만들어줍시다.
1 2 3 4 5 | #views/posts/index.html.erb
<th>Title</th> <th>Body</th> <th>Like</th> <th>LinkTo</th> <th colspan="3"></th> | cs |
1 2 3 | #views/posts/index.html.erb <td><%= post.title %></td> <td><%= post.body %></td> <td><%= post.likes.size %> 명</td> | cs |
3번째 줄의 코드를 각각 추가해줍시다.
자 이렇게 하면 좋아요 기능은 구현 완료되었습니다.
여기서 추가로 로그아웃 링크와 현재 로그인한 유저의 이메일을 확인할 수 있도록 구현해 봅시다.
먼저, c9주소/users/sign_in에 들어가서 회원가입을 해주세요!
config/initializers/devise.rb 파일에서 ctrl+f ‘sign_out’ 검색해서
:delete를 :get으로 바꿔주세요.
1 2 3 4 | #app/views/posts/index.html.erb <h2>USER: <%= current_user.email%></h2> | cs |
1 2 3 | #app/views/posts/index.html.erb <a href= '/users/sign_out'> Log out </a> |
마지막으로 해줘야 할 작업이 남아있습니다.
바로! 로그인한 유저만 글의 목록을 볼 수 있고 수정, 삭제, 로그아웃을 할 수 있도록 설정해줍시다.
1 2 3 4 5 6 7 8 | #app/controllers/posts_controller.rb def index @posts = Post.all unless user_signed_in? redirect_to '/users/sign_in' end end | cs |
여기까지 잘 실행된다면 좋아요 기능은 완료!
Sunspot & Solr
먼저 젬을 사용하기 전에 Sunspot과 Solr에 대해서 간략하게 알아볼까요?
[Solr]
Apache Lucene 프로젝트에 기반을 둔 검색 엔진으로써 Java언어로 작성되었습니다.
단독 애플리케이션 서버 형태로 작동하며, REST 형식의 API를 제공합니다.
오픈소스 기업용 검색엔진입니다.
[Sunspot]
sunspot_rails gem을 통해 solr 라이브러리를 사용할 수 있도록 해주며, full text search를 가능하게 해줍니다.
자 그럼 gem을 설치해볼까요?
1 2 3 4 | #Gemfile gem 'sunspot_rails' gem 'sunspot_solr' | cs |
1 2 3 | #bash창 bundle install | cs |
gem 설치 완료!
1 2 3 | #bash창 rake sunspot:solr:start | cs |
Solr는 분리된 프로세스로 작동하기때문에 Solr server는 따로 작동시켜주어야합니다.
* 만약 서버를 끄려면 rake sunspot:solr:stop
[Post 모델 설정]
1 2 3 4 5 | #app/model/post.rb validates_presence_of :title, :body searchable do text :title end | cs |
현재, 우리는 Post 모델 중 title 칼럼만 검색될 수 있도록 설정해둡시다.
만약, body 칼럼도 검색하고 싶다면! :body도 추가해주세요!
(밑에서 더 자세하게 배워봅시다.)
[액션 만들기]
1 2 3 4 5 6 7 | #config/routes.rb resources :posts do collection do get :search end end | cs |
[Search 메소드 정의]
1 2 3 4 5 6 7 8 9 10 11 12 | #app/controllers/posts_controller.rb def search @posts = Post.search do keywords params[:query] end.results respond_to do |format| format.html { render :action => "index" } format.xml { render :xml => @posts } end end | cs |
1 2 3 4 | #app/views/index.html.erb <%= form_tag search_posts_path, :method => :get do %> <%= text_field_tag :query, params[:query] %> <%= submit_tag "Search!" %> <% end %> | cs |
Post.search는 sunspot search 메소드입니다.
검색어 입력창에서부터 넘어온 값을 바탕으로 검색을 한 후 결과들만 뽑아줍니다.
end.results => 검색한 값의 결과만 깔끔하게 보여준다!
respond_to do |format| end => 사용자가 원하는 포맷으로 리턴해준다!
ex) html, js, xml, json ...
[라우트 설정]
1 2 3 | #config/routes.rb get 'posts/search' => 'posts#search' |
준비 끝!
RUN! 검색해볼까요?
Great을 검색했을 때 나오는 결과입니다.
그렇다면 Body 칼럼의 내용도 검색해볼까요?
아까 위에서는 title만 검색범위에 넣었었죠? 이번에는 body도 추가해봅시다.
분명 body 칼럼을 추가했는데 없다고 뜨네요?
현재 존재하는 데이터들을 reindex 시켜준 후에 다시 검색해봅시다!
1 2 3 | #bash창 rake sunspot:reindex | cs |
검색 성공!
이번 교육은 여기까지!
'교육팀과 함께하는 > ruby on rails' 카테고리의 다른 글
[방학 2주차] REST API 정복하기 - (1) RESTful & (2) 다음 카카오 검색 API & (3) 네이버 성인검색어 판별 API (3) | 2017.08.14 |
---|---|
[방학 7주차] AWS 배포하기 (1) | 2017.08.13 |
[방학 6주차] 권한 설정하기 (0) | 2017.08.04 |
[방학 2주차] 소셜로그인 (0) | 2017.08.03 |
[방학 1주차] 스캐폴딩과 리소스 라우팅 (0) | 2017.07.09 |