首页 > 解决方案 > Rails 切换布尔值

问题描述

我的模型“评论”有布尔值 - 最好,它可以是真假。这是我的控制器 comments_controller.rb 的一部分:

class CommentsController < ApplicationController
  

    before_action :find_comment, only: [:choose_best]
    
      def create
        @post = Post.find(params[:post_id])
        @comment = @post.comments.create(params[:comment].permit(:name, :comment, :user_id, :best))
        respond_to do |format|
          format.html { redirect_to post_path(@post) }
          format.js
        end
      end
    
      def choose_best
        @comment.choose_best!
        redirect_to post_path(@post)
      end
    
      private
    
      def find_comment
        @post = Post.find(params[:post_id])
        @post_id = @post[:post_id]
        @comment = @post.comments.find(params[:id])
      end
    
    end

这是comment_model.rb:

class Comment < ApplicationRecord
      belongs_to :post
    
      scope :best_comments,     -> { where(best: true) }
      scope :not_best_comments, -> { where(best: false) }
    
      def choose_best!
          ActiveRecord::Base.transaction do
            unless best?
              post.comments.update_all(best: false)
              update!(best: true)
            end
          end
        end
    end

这里是路线:

resources :posts do
    resources :comments do
      resources :answers
      member do
        patch :choose_best
      end
    end
  end

这是html:

<div id="post-id" data-post-id="<%= @post_id %>"> </div>
       <% if @comment.best? %>
          <h1>best</h1>
          <% else %>
          <h1>not best</h1>
          <% end %>
        <%=link_to 'Best', choose_best_post_comment_path(comment.post, comment), method: :patch, remote: true,
                   class: 'best-answer-btn btn btn-success', id: "best-comment-link-#{comment.id}"%>
</div>

这是我的 js 文件以获得最佳评论:

<% if @comment.best? %>
$('.comments').html('<%= j render 'posts/form', post: @post.comment %>');
$('.comment-form').on('click', function (e) {
    e.preventDefault();
    $(this).hide();
    var comment_id = $(this).parents('.comment').data('commentID');
    $('#best-comment-link-' + comment_id).hide();
})
<% end %>

所以问题是,当我按下“最佳”按钮时 - 它会为此评论切换布尔值,但是当我尝试按下此按钮时,没有任何变化。我试图让 def 每个帖子只保留一个最佳评论(用户按下“最佳”按钮,另一个最佳评论值变为假,按下变为真),所以问题可能出在此。

标签: ruby-on-railsajaxboolean

解决方案


一个更好的解决方案是简单地向 post 表添加一个额外的外键列:

class AddBestCommentToPosts < ActiveRecord::Migration[6.1]
  def change
    add_reference :posts, :best_comment, null: true, foreign_key: { to_table: :posts }
  end
end
class Post
  has_many :comments
  belongs_to :best_comment, 
    class_name: 'Comment', 
    optional: true
end
def choose_best
  if @post.update(best_comment: @comment)
    head :ok
  else
    head :unprocessable_entity
  end
end

由于这是一个单列,因此您不必担心一个以上的评论可能同时具有“最佳”标志的极端情况。您还可以非常有效地预先加载关联。


推荐阅读