Together网站搭建之踩坑系列6

写在前面

这是功能实现的第五篇,扯一扯如何添加评论区,并使用ajax优化

完整作品源码及效果,看这里作品网站, 作品源码

目录

正文

上效果图先:

功能描述:用户可以新增,删除自己的评论。

步骤如下:

  • 新增review model,终端运行:

    rails g model review comment:string user_id:integer event_id:integer
    rake db:migrate
    
  • 建立review与event,user的关系:

    • review.rb中,添加:

      belongs_to :user
      belongs_to :event
      
    • event.rb中,添加:

      has_many :reviews
      
    • user.rb中,添加:

      has_many :reviews
      
  • 编辑config/routes.rb,在resources :events中添加:

      resources :events do
      + resources :reviews
        .....
        end
    
  • 新建review controller

    rails g controller reviews
    
  • 编辑app/controllers/reviews_controller.rb

    class ReviewsController < ApplicationController
      before_action :authenticate_user!
    
      def new
        @event = Event.find(params[:event_id])
        @review = Review.new
      end
    
      def create
        @event = Event.find(params[:event_id])
        @review = Review.new(review_params)
        @review.event = @event
        @review.user = current_user
        @review.save
        redirect_to :back, alert: "评论已经创建"
      end
    
      def destroy
        @event = Event.find(params[:event_id])
        @review = Review.find(params[:id])
        @review.destroy
        redirect_to :back, alert: "评论已经删除"
      end
    
      private
    
      def review_params
        params.require(:review).permit(:comment)
      end
    
    end
    
  • 编辑app/controllers/events_controller.rb, 在show部分,添加:

    ......
    def show
      @event = Event.find(params[:id])
    + @reviews = @event.reviews.all
    end
    ......
    
  • 编辑event的show.html.erb,给评论区腾出位置,这里用了两次partial来引用review,后面会建相应的文档:

    ......
    <!-- 活动讨论区 -->
      <div class="event_reviews">
        <div class="row">
          <div class="col-md-8 col-md-offset-2">
            <%= render :partial => "reviews/form", :locals => {:event => @event } %>
            <hr>
            <% if @reviews.blank? %>
              <p>该活动还没有人讨论,来侃几句吧?</p>
            <% else %>
            <div id="reviews_list">
              <% @reviews.each do |review| %>
            <%= render :partial => "reviews/review", :locals => { :review => review }%>
              <% end %>
            </div>
            <% end %>
            <hr>
          </div>
        </div>
      </div>
     ......
    

  • app/views/reviews下,新增_review.html.erb, _form.html.erb_review.html.erb用来显示评论区列表,_form.html.erb则用于新增评论。

    • 编辑_review.html.erb

      <div id="reivew-<%= review.id %>" class="reviews" style="text-align: left;">
          <!-- 显示用户头像 -->
        <ul>
          <div class="user_avatar" style="float: left;">
            <% if review.user.avatar.present? %>
              <%= image_tag(review.user.avatar.thumb.url, class: "review_avatar")%>
            <% else %>
              <%= image_tag("https://ws4.sinaimg.cn/large/006tNc79gy1fj8fv5d1tdj30zk0npdig.jpg", class: "review_avatar")%>
            <% end %>
          </div>
        </ul>
        <!-- 显示其他信息 -->
          <div class="row">
            <div class="col-md-9 review-user-info">
              <%= review.user.display_name %>
            </div>
            <div class="col-md-3">
              <%= review.created_at %>
            </div>
          </div>
          <div class="review-comment">
            <%= review.content %>
          </div>
          <!-- 用户可以删除自己的评论 -->
          <% if current_user == review.user %>
          <div class="pull-right">
            <%= link_to("delete", event_review_path(review.event,review), method: :delete, :remote => true)%>
          </div>
        <% end %>
      </div>
      
    • 编辑_form.html.erb

      <div class="contain">
        <div class="row" style=" margin-top: 50px;">
          <div class="col-md-12">
            <%= simple_form_for [@event, @event.reviews.build ], :remote => true do |f| %>
              <div class="form-group">
                <%= f.input :content, label: "吐糟或者提问,请随意", input_html: { class: "form-control"}%>
              </div>
              <div class="form-action">
                <%= f.submit "我来说两句", disable_with: "Submiting....", class: "btn btn-danger"%>
              </div>
            <% end %>
          </div>
        </div>
      </div>
      
  • 编辑app/controllers/events_controller.rb, 拿掉create, destroy 的redirect_to:

    ......
    def create
        @event = Event.find(params[:event_id])
        @review = Review.new(review_params)
        @review.event = @event
        @review.user = current_user
        @review.save
      - redirect_to :back, alert: "评论已经创建"
      end
    
      def destroy
        @event = Event.find(params[:event_id])
        @review = Review.find(params[:id])
        @review.destroy
      - redirect_to :back, alert: "评论已经删除"
      end
      ......
    
  • 新增app/views/reviews/create.js.erb, app/views/reviews/destroy.js.erb, 分别编辑:

    • app/views/reviews/create.js.erb

      <% if @review.valid? %>
        $("#reviews_list").prepend("<%=j render :partial => "review", :locals => {:review => @review } %>");
        $("#review_content").val("");
      <% else %>
        alert("评论失败");
      <% end %>
      
    • app/views/reviews/destroy.js.erb中,

      $("#reivew-<%= @review.id %>").remove();
      

大功告成!试试吧!美化部分,可以根据需要写相应的CSS。


这里说明一下:

  • rails5.0以前的版本已经默认安装gem 'jquery-rails', 如果你版本过高,需要自行安装,不然ajax部分会无法正常实现
  • 涉及ajax的部分,没有说得太细,可自行Google ajax相关内容了解。