Rails 开关布尔值

Rails switch boolean value

我的模型有布尔值 'comment' - 最好,它可以是真或假。这是我的控制器的一部分 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 %>

所以问题是,当我按下按钮 'best' - 它会切换此评论的布尔值,但是当我尝试将此按钮按下到另一个评论时 - 没有任何变化。我试图让 def 只保留每个 post 的一个最佳评论(用户按下 'best' 按钮,另一个最佳评论值变为 false 并按下变为 true),所以问题可能在于此。

一个更好的解决方案是简单地向帖子 table:

添加一个额外的外键列
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

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