ruby-on-rails - 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 每个帖子只保留一个最佳评论(用户按下“最佳”按钮,另一个最佳评论值变为假,按下变为真),所以问题可能出在此。
解决方案
一个更好的解决方案是简单地向 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
由于这是一个单列,因此您不必担心一个以上的评论可能同时具有“最佳”标志的极端情况。您还可以非常有效地预先加载关联。
推荐阅读
- javascript - 为什么我在使用 async/await 时会收到多个响应?
- java - 为什么链表中的head是变化的?
- video - Kultura 3D 360 视频播放
- node.js - 连接到 Node.js 服务器时出错... parsererror SyntaxError: Unexpected token '<'
- file - 使用骆驼文件语言
- xamarin - 使用 Xamarin 的带有箭头的操作表
- node.js - AWS S3上传0 B文件-node.js
- spring-boot - `SpringApplicationBuilder` 是否可以用于连接`@SpringBootApplication` 和`@SpringBootTest` 之间的父/子关系?
- vb.net - Selenium VB.Net 2019 保存画布图像
- r - 对多个时间间隔求和,而不计算 lubridate 中的重叠时间