Как показать частичное использование JS в Rails View? - PullRequest
0 голосов
/ 20 апреля 2020

В моем приложении на Rails 6 я хочу модели Post и Comment. Когда пользователь просматривает сообщение, он может оставить комментарий. Комментарии отображаются на posts#show в виде текста со ссылкой для редактирования.

Когда нажата ссылка для редактирования, я хочу показать фрагмент, чтобы пользователь мог редактировать комментарий.

Однако, верно теперь, когда нажата ссылка редактирования, я вижу ошибку 500 в консоли Chrome и не знаю почему.

Вот что я вижу в консоли:

GET http://localhost:3000/posts/7/comments/1/edit 500 (Internal Server Error)

(anonymous) @ VM6383:1
window.XMLHttpRequest.send @ main.js?attr=JpIV9sz…9rF02y-O8AJVkZ:1063
./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js.Rails.ajax @ rails-ujs.js:216
./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js.Rails.handleRemote @ rails-ujs.js:652
(anonymous) @ rails-ujs.js:172

Пример URL для ссылки редактирования, которая отображается в представлении: http://localhost:3000/posts/7/comments/1/edit

Мой код:

 # posts_controller

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  # GET /posts
  def index
    @pagy, @posts = pagy(Post.where(account_tag_id: params[:account_tag]).sort_by_params(params[:sort], sort_direction))
    @tags = current_account.account_tags
    @tag = AccountTag.find(params[:account_tag])
  end

  # GET /posts/1
  def show
    @comment = Comment.new
    @pagy, @comments = pagy(@post.comments.sort_by_params(params[:sort], sort_direction))
  end

  # GET /posts/new
  def new
    @post = Post.new
    @account_tag = AccountTag.find_by_name(params[:topic])
  end

  # GET /posts/1/edit
  def edit
  end

  # POST /posts
  def create
    @post = Post.new(post_params)
    @post.account_user_id = current_account_user.id
    current_account_user.tag(@post, on: :tags, with: params[:post][:tag_list])

    if @post.save
      redirect_to @post, notice: 'Post was successfully created.'
    else
      render :new
    end
  end

  # PATCH/PUT /posts/1
  def update

    if @post.update(post_params)
      redirect_to @post, notice: 'Post was successfully updated.'
    else
      render :edit
    end
  end

  # DELETE /posts/1
  def destroy
    @post.destroy
    redirect_to posts_url, notice: 'Post was successfully destroyed.'
  end

  # GET /posts/feed
  def feed
    @account_tags = current_account_user.account_tags
    @pagy, @posts = pagy(Post.where(account_tag_id: @account_tags).sort_by_params(params[:sort], sort_direction))
  end


  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.find(params[:id])
    end

    # Only allow a trusted parameter "white list" through.
    def post_params
      params.fetch(:post, {}).permit(:title, :content, :post_type_id, :account_tag_id)
    end
end


 # comments_controller

class CommentsController < ApplicationController
  before_action :authenticate_user!
  before_action :load_post, except: [:upvote, :downvote, :set_flag]
  before_action :set_user_comment, only: [:edit, :update, :destroy, :cancel_update]
  before_action :set_comment, only: [:upvote, :downvote, :set_flag]

  # GET /comments/1/edit
  def edit
    respond_to do |format|
      format.js
    end
  end

  # POST /comments
  def create
    @comment = @post.comments.create(comment_params)
    @comment.account_user = current_account_user

    if @comment.save
      redirect_to @post, notice: "Thanks for commenting!"
    else
      redirect_to @post
    end
  end

  # PATCH/PUT /comments/1
  def update
    if @comment.update(comment_params)
      format.js
    else
      format.js { render :edit }
    end
  end

  def cancel_update
    respond_to do |format|
      format.js { render :update }
    end
  end

  # DELETE /comments/1
  def destroy
    @comment.destroy
    redirect_to @post, notice: "Your comment has been successfully deleted."
  end

  # using act as votable for upvote
  def upvote
    @comment.upvote_by current_account_user

    respond_to do |format|
      format.html { redirect_back(fallback_location: root_path) }
      format.js
    end
  end

  # using act as votable for upvote
  def downvote
    @vote = Vote.where(votable_type: 'Comment', votable_id: @comment.id, voter_id: current_account_user.id)
    @vote.destroy(@vote.id)

    respond_to do |format|
      format.html { redirect_back(fallback_location: root_path) }
      format.js
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_comment
      @comment = Comment.find(params[:id])
    end

    # Only allow a trusted parameter "white list" through.
    def comment_params
      params.require(:comment).permit(:content)
    end

    def set_user_comment
      @comment = current_account_user.comments.find(params[:id])
    end

    def load_post
      @post = Post.find(params[:post_id])
    end

end


# comments/edit.js.erb

$('#content_<%= @comment.id %>').html(
  '<%= j render(partial: 'comments/edit_content', locals: { comment: @comment, post: @post }) %>'
 );


# comments/edit_content.html.erb

<%= simple_form_for [post, comment], remote: true do |f| %>
  <% if comment.errors.any? %>
    <div class="alert alert-warning">
      <% comment.errors.full_messages.each do |msg| %>
        <%= msg %>
      <% end %>
    </div>
  <% end %>
  <div class="media media-post">
    <div class="media-body">
      <%= f.input :content, label: false %>
      <div class="media-footer pull-right">
        <%= f.submit 'Update', class: "btn btn-info btn-sm" %>
        <%= link_to 'Cancel',
          cancel_update_post_comment_path(comment.post.id, comment.id),
          remote: true,
          class: "btn btn-info btn-sm"
        %>
      </div>
    </div>
  </div>
<% end %>


# routes.rb

 resources :posts do
    resources :comments, except: [:index, :show, :new] do
      member do
        get "edit" # I tried with this line, and without
        get "cancel_update", to: "comments#cancel_update"
      end
    end
  end


# comments/show_content

<%= simple_format comment.content %>
<%= render 'comments/actions', comment: comment %>


# comments/action

<% if comment.user_id == current_user.id %>
  <li><%= link_to 'Edit', edit_post_comment_path(comment.post.id, comment.id), remote: true %></li>
  <li><%= link_to 'Delete', post_comment_path(comment.post.id, comment.id), method: :delete %></li>
<% end %>

1 Ответ

0 голосов
/ 21 апреля 2020

Одна проблема, которую я вижу из кодовой базы, которой вы поделились, заключается в том, что шаблон edit имеет проблему с кавычками

# comments/edit.js.erb

$('#content_<%= @comment.id %>').html("<%= j render(partial: 'comments/edit_content', locals: { comment: @comment, post: @post }) %>");

Надеюсь, что это решит проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...