皆さんこんにちわ!!
今日もプログラミングしていますか?
今回は詳細ページにコメント星機能をつけていく機能を紹介します!!
注意:大前提としていいね機能を実装していないと実装できません!!
.ターミナル
rails g model Review eve:integer content:string user:references tweet:references
rails db:migrate
app/models/user.rb
has_many :reviews, dependent: :destroy
app/models/tweet.rb
has_many :reviews, dependent: :destroy
ターミナル
rails g controller reviews
app/controllers/reviews_controller.rb
class ReviewsController < ApplicationController
before_action :authenticate_user!
def create
@tweet = Tweet.find(params[:tweet_id])
review = @tweet.reviews.build(review_params)
review.user_id = current_user.id
if review.save
flash[:success] = "コメントしました"
redirect_back(fallback_location: root_path)
else
flash[:success] = "コメントできませんでした"
redirect_back(fallback_location: root_path)
end
end
private
def review_params
params.require(:review).permit(:eve, :content)
end
end
app/controllers/tweets_controller.rb
def show
@tweet = Tweet.find(params[:id])
# 追記ここから
@reviews = @tweet.reviews
@review = Review.new
# 追記ここまで
end
helperの編集
app/helper/tweets_helper.rb
module TweetsHelper
def getPercent(number)
if number.present?
calPercent = number/5.to_f * 100
# calPercent = number/10.to_f * 100
#↑10段階評価の際は2行目コメントアウトを外して、1行目をコメントアウト。
percent = calPercent.round
#↑CSSは小数が含まれると、widthの幅を指定できないので四捨五入して整数化。
return percent.to_s
else
return 0
end
end
end
routes.rb
Rails.application.routes.draw do
resources :tweets do
resources :likes, only: [:create, :destroy]
#追記箇所
resources :reviews, only: [:create]
# ここまで
end
end
app/views/tweets/show.html.erb
# 割愛
# 追記ここから
<div class="review-wrapper">
<p>一覧</p>
<% @reviews.each do |c| %>
<div>
<%= c.user.email unless c.user.blank? %>
<br>
<div>
<h2>口コメ:
<span class="star-rating">
<span class="star-rating-front" style="width: <%= getPercent(c.eve) %>%;">★★★★★</span>
<span class="star-rating-back">★★★★★</span>
</span>
</h2>
<%= c.content %>
</div>
<br>
<% end %>
<% if user_signed_in? %>
<%= form_with(model: [@tweet, @review], local: true) do |f| %>
<h5>評価基準</h5>
<div class="post_form">
<%= f.radio_button :eve, 5 ,id: 'star6'%>
<label for="star6"><span class="text">Great</span>★</label>
<%= f.radio_button :eve, 4 ,id: 'star7'%>
<label for="star7"><span class="text">good</span>★</label>
<%= f.radio_button :eve, 3 ,id: 'star8'%>
<label for="star8"><span class="text">normal</span>★</label>
<%= f.radio_button :eve, 2 ,id: 'star9'%>
<label for="star9"><span class="text">but</span>★</label>
<%= f.radio_button :eve, 1 ,id: 'star10'%>
<label for="star10"><span class="text">worse</span>★</label>
</div>
<%= f.text_area :content %>
<%= button_tag type: "submit" do %>
<i class="far fa-reviews"></i> 評価する
<% end %>
<% end %>
<% end %>
</div>
#追記ここまで
review.scss
/* 以下詳細ページの星用のCSS */
.star-rating {
position: relative;
display: inline-block;
width: 5em;
height: 1em;
font-size: 25px;
}
.star-rating-front {
display: inline-block;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
color: #ffcc33;
}
.star-rating-back {
display: inline-block;
color: #ccc;
}
.post_form{
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
}
.post_form input[type='radio']{
display: none;
}
.post_form label{
position: relative;
padding: 10px 10px 0;
color: gray;
cursor: pointer;
font-size: 30px; /*星の大きさを変更するときはここ*/
}
.post_form label .text{
position: absolute;
left: 0;
top: 0;
right: 0;
text-align: center;
font-size: 9px; /*星の上の説明書きの大きさを変更するときはここ*/
color: gray;
}
.post_form label:hover,
.post_form label:hover ~ label,
.post_form input[type='radio']:checked ~ label{
color: #ffcc00;
}
以上になります!!! いろんな機能実装していこう!!!
追加:もしユーザーが一度のみしか投稿させない場合
review.rb
class Review < ApplicationRecord
belongs_to :user
#追加部分
validates :user_id, uniqueness: { scope: :register_id }
#ここまで
end