Ruby on Rails - 댓글 실시간 로딩

19248 단어 reactrailswebdevruby
이 포스트의 목표는 ruby ​​on rails에 대한 코멘트를 실시간으로 로딩하는 것이었습니다. 이 데모에서처럼:

screen-demo



필기 해:

This is a continuation of my previous blog post here: . I highly suggest that you look at it since it will be used as a base for this one. If you wanna get the base first, you could check this.



시작해 볼까요?

  • 다음을 Gemfile에 추가하여 설치react-rails gem합니다.

    gem 'react-rails'
    

    그런 다음 번들 설치를 실행하십시오.

    설치 후 콘솔에 다음 명령을 실행합니다.

    $ bundle install
    $ rails webpacker:install         # OR (on rails version < 5.0) rake webpacker:install
    $ rails webpacker:install:react   # OR (on rails version < 5.0) rake webpacker:install:react
    $ rails generate react:install
    


  • 우리는 API에 jquery를 사용할 것입니다. 다음을 사용하여 jquery를 설치하십시오.

     $ yarn add jquery
    

    이 코드를 environment.js에 추가하십시오.

     const webpack = require('webpack')
     environment.plugins.prepend('Provide',
       new webpack.ProvidePlugin({
         $: 'jquery/src/jquery',
         jQuery: 'jquery/src/jquery'
       })
    )
    
    module.exports = environment
    

    'app/javascript/packs/'에서 새로 생성된 application.js를 수정합니다.

    // This file is automatically compiled by Webpack, along with any other files
    // present in this directory. You're encouraged to place your actual application logic in
    // a relevant structure within app/javascript and only use these pack files to reference
    // that code so it'll be compiled.
    
    // Support component names relative to this directory:
    var componentRequireContext = require.context("components", true);
    var ReactRailsUJS = require("react_ujs");
    ReactRailsUJS.useContext(componentRequireContext);
    
    require("@rails/ujs").start()
    require("jquery")
    

    'app/views/layouts/'의 헤드 레이아웃에 application.js를 추가합니다.

    <%= javascript_pack_tag 'application' %>
    


  • 반응 구성 요소를 만듭니다.

    $ rails g react:component CommentSection commentsPath:string
    

    이것은 주석을 실시간으로 로드하는 데 사용할 반응 구성 요소를 생성합니다. 'commentsPath:string'은 API URL을 구성 요소에 전달할 소품입니다.

  • 이것을 Gemfile에 추가한 후 활성 모델 직렬 변환기 gem을 설치합니다.

    gem 'active_model_serializers'
    

    콘솔에 이것을 입력하여 주석 직렬 변환기를 만듭니다.

    $ rails g serializer Comment
    

    그런 다음 주석 직렬 변환기에 텍스트 필드를 추가합니다.

    class CommentSerializer < ActiveModel::Serializer
        attributes :id, :text
    end
    


  • 이제 API에 사용할 컨트롤러를 생성합니다.

    먼저 API 폴더를 만듭니다. rails 앱의 컨트롤러 폴더로 이동한 다음 다음을 수행합니다.

    $  mkdir api
    

    그런 다음 새로 만든 폴더로 이동하여 사용할 컨트롤러를 만듭니다.

    $ touch posts_controller.rb
    

    이 코드로 posts_controller.rb를 편집하십시오.

    class Api::PostsController < ApplicationController
        before_action :set_post, only: [:comments]
    
        def comments
            render json: @post.comments, each_serializer: CommentSerializer
        end
    
        private
    
        def set_post
           @post = Post.find(params[:id])
        end
     end
    

    posts#show는 주석 배열을 반환해야 합니다.

  • config/routes.rb에 API 경로를 추가합니다.

    Rails.application.routes.draw do
     # other routes
    
     namespace :api do
        resource :posts, only: [], defaults: {format: "json"} do
            member do
                get "/:id/comments" => "posts#comments", as: "comments"
            end
        end
     end
    end
    

    콘솔 터미널에 대한 'rails route'를 확인하여 새로 추가된 경로의 경로 이름을 가져옵니다. 제 경우에는 'comments_api_posts_path'입니다.

  • post#show 보기에 반응 구성 요소를 추가합니다. 반응 구성 요소에서 방금 만든 새 경로 이름을 전달합니다.

    <!--app/views/posts/show.html.erb-->
    <p id="notice"><%= notice %></p>
    
    <%= @post.title %>
    <br>
    <%= @post.text %>
    <br>
    
    <b>Comments</b>
    <br>
    
    <%= react_component("CommentSection", { commentsPath: comments_api_posts_path(id: @post.id)}) %>
    
    <%= render "comments/form", comment: @comment, post_id: @post.id%>
    
    <%= link_to 'Edit', edit_post_path(@post) %> |
    <%= link_to 'Back', posts_path %>
    

    commentPath는 반응 구성 요소의 소품으로 경로 아래로 전달됩니다.

  • React 구성 요소 CommentSection.js를 업데이트합니다.

    import React from "react"
    import PropTypes from "prop-types"
    
    class CommentSection extends React.Component {
       constructor(props){
          super(props);
    
          this.state = {
              comments: []
          }
       }
    
       componentDidMount(){
           //Run fetchComments() for the first time
           this.fetchComments();
    
           //Set Interval for running fetchComments()
           this.interval = setInterval(() =>{
               this.fetchComments();
           }, 1000);
       }
    
       componentWillUnmount(){
           // Clear the interval right before component unmount
           clearInterval(this.interval);
       }
    
       // Fetches Comments
       fetchComments(){
    
           $.ajax({
               url: this.props.commentsPath,
               dataType: 'json',
               success: function (result){
                   //Set state based on result
                   this.setState({comments: result})
              }.bind(this)
           });
       }
    
       render () {
           return (
               <React.Fragment>
                   <ul>
                       {
                         this.state.comments.map(function(comment, index){
    
                         return <li key={index}>{comment.text}</li>
                       })
                       }
                  </ul>
               </React.Fragment>
           );
       }
     }
    
     export default CommentSection
    

    약간의 설명. fetchComments() 함수는 commentPath props 값(현재 게시물의 API 경로 값 포함)을 기반으로 게시물의 댓글을 가져옵니다. 가져오기의 결과는 주석 배열을 반환하고 구성 요소에 의해 렌더링되는 상태로 설정됩니다.

  • 'app/views/comments/_form.html.erb' 및 comments_controller.rb에서 양식을 변경합니다.

     <!-- app/views/comments/_form.html.erb -->
     <!--  add 'local:false' in the form_with-->
    
     <%= form_with(model: comment, local: false) do |form| %>
    



     # app/controllers/comments_controller.rb
     # edit create action
    
     def create
         @comment = Comment.new(comment_params)
    
         if @comment.save
             respond_to do |format|
                 format.js{ render :js => "document.getElementById('comment_text').value = '';" }
             end
         end
     end
    

    자바 스크립트는 주석 양식을 제출한 후 텍스트를 제거합니다.

  • 그리고 마지막 단계입니다! 서버를 다시 시작하고 로컬 호스트를 확인하십시오.

    코드를 확인하고 싶다면 Github Repository 으로 가세요.

    좋은 웹페이지 즐겨찾기