为什么数据库会在创建新评论时回滚? Ruby 在 Rails
Why does database rollback on creating a new comment? Ruby on Rails
我有一个问题,过去一周我一直在努力解决。我正在尝试使用 closure_tree gem 创建嵌套评论系统。我终于想出了如何将 parent_id 作为参数的一部分传递,现在整个哈希已正确填充到服务器日志中,但是每次我尝试保存回复时,我的日志都会在评论保存之前显示回滚.所有评论 belong_to wad.
这是我的评论控制器中的相关代码:
class CommentsController < ApplicationController
before_action :find_wad
before_action :find_comment, only: [:destroy, :edit, :update, :comment_owner, :comment_params]
before_action :comment_owner, only: [:destroy, :edit, :update]
def create
if params[:comment][:parent_id].to_i > 0
parent = Comment.find_by(params[:comment].delete(:parent_id))
@comment = parent.children.build(comment_params)
parent_id = parent.id
else
@comment = @wad.comments.build(comment_params)
parent_id = @comment.id
end
@comment.user_id = current_user.id
@comment.save
if @comment.save
flash[:success] = 'Your comment was successfully added!'
redirect_to wad_path(@wad)
else
render 'new'
end
end
def new
@comment = Comment.new(parent_id: params[:parent_id])
end
private
def find_wad
@wad = Wad.find(params[:wad_id])
end
def find_comment
@comment = @wad.comments.find_by(params[:id])
end
def comment_params
params.require(:comment).permit(:content, :wad_id, :user_id, :parent_id)
end
def comment_owner
unless current_user.id == @comment.user_id
flash[:notice] = "Action Restricted"
redirect_to @wad
end
end
end
这是我在评论视图的 _reply 部分中使用的回复表单:
<%= form_for([@wad, @comment]) do |f| %>
<%= f.hidden_field :parent_id %>
<%= f.text_area :content %>
<%= f.submit %>
<% end %>
以下是我尝试输入回复评论时服务器日志中发生的情况:
Started POST "/wads/1/comments" for 127.0.0.1 at 2018-02-04 14:20:04 -0800
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LYk07p6h3+RJ6kfx+rixaGJ0a56XPt29v7mFFbCQ+H+Gr5PjzzkrWOWfShCuKwFEIShwEz8Om7IsLjGI3hN0vw==", "comment"=>{"parent_id"=>"136", "content"=>"elmle"}, "commit"=>"Create Comment", "wad_id"=>"1"}
Wad Load (0.2ms) SELECT "wads".* FROM "wads" WHERE "wads"."id" = ? ORDER BY "wads"."created_at" DESC LIMIT ? [["id", 1], ["LIMIT", 1]]
Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE (136) LIMIT ? [["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.1ms) begin transaction
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.1ms) rollback transaction
(0.1ms) begin transaction
(0.0ms) rollback transaction
我的任何模型中都没有 attr_accessor - 只有正确定义的 has_many 和 belongs_to 关系。有人知道为什么会这样吗?
Wad 型号:
class Wad < ApplicationRecord
acts_as_votable
belongs_to :user
has_many :comments, dependent: :destroy
default_scope -> { order(created_at: :desc) }
validates :user_id, presence: true
validates :category, presence: true
validates :long_form, presence: true, length: { maximum: 1000 }
validates :short_form, presence: true, length: { maximum: 140 }
validates :problem_state, presence: true, length: { maximum: 50 }
end
评论模型:
class Comment < ApplicationRecord
acts_as_tree order: 'created_at DESC'
belongs_to :wad
belongs_to :user
end
用户模型的相关部分:
class User < ApplicationRecord
acts_as_voter
has_many :wads, dependent: :destroy
has_many :comments
据我所见,参数是:
{"comment"=>{"parent_id"=>"136", "content"=>"elmle"}, "commit"=>"Create Comment", "wad_id"=>"1"}
在这种情况下,我们将达到以下条件:
if params[:comment][:parent_id].to_i > 0
parent = Comment.find_by(params[:comment].delete(:parent_id))
@comment = parent.children.build(comment_params)
parent_id = parent.id
其中从 params["comment"]
创建的新 Comment 对象仅包含 parent_id
和 content
。
因此,正在创建没有 wad_id
键的新对象,而 belongs_to
可能需要您的模型
当您使用
Comment.find_by(params[:comment].delete(:parent_id))
您从 params[:comment] 的散列中删除了您的 :parent_id,您需要从 comment_params 中的许可中删除。尝试像这样改变你的方法,它应该有效:
def comment_params
params.require(:comment).permit(:content, :wad_id, :user_id)
end
编辑
另外我认为你需要更改
中的第一个命令
parent = Comment.find_by_id(params[:comment].delete(:parent_id))
或
parent = Comment.find(params[:comment].delete(:parent_id))
我有一个问题,过去一周我一直在努力解决。我正在尝试使用 closure_tree gem 创建嵌套评论系统。我终于想出了如何将 parent_id 作为参数的一部分传递,现在整个哈希已正确填充到服务器日志中,但是每次我尝试保存回复时,我的日志都会在评论保存之前显示回滚.所有评论 belong_to wad.
这是我的评论控制器中的相关代码:
class CommentsController < ApplicationController
before_action :find_wad
before_action :find_comment, only: [:destroy, :edit, :update, :comment_owner, :comment_params]
before_action :comment_owner, only: [:destroy, :edit, :update]
def create
if params[:comment][:parent_id].to_i > 0
parent = Comment.find_by(params[:comment].delete(:parent_id))
@comment = parent.children.build(comment_params)
parent_id = parent.id
else
@comment = @wad.comments.build(comment_params)
parent_id = @comment.id
end
@comment.user_id = current_user.id
@comment.save
if @comment.save
flash[:success] = 'Your comment was successfully added!'
redirect_to wad_path(@wad)
else
render 'new'
end
end
def new
@comment = Comment.new(parent_id: params[:parent_id])
end
private
def find_wad
@wad = Wad.find(params[:wad_id])
end
def find_comment
@comment = @wad.comments.find_by(params[:id])
end
def comment_params
params.require(:comment).permit(:content, :wad_id, :user_id, :parent_id)
end
def comment_owner
unless current_user.id == @comment.user_id
flash[:notice] = "Action Restricted"
redirect_to @wad
end
end
end
这是我在评论视图的 _reply 部分中使用的回复表单:
<%= form_for([@wad, @comment]) do |f| %>
<%= f.hidden_field :parent_id %>
<%= f.text_area :content %>
<%= f.submit %>
<% end %>
以下是我尝试输入回复评论时服务器日志中发生的情况:
Started POST "/wads/1/comments" for 127.0.0.1 at 2018-02-04 14:20:04 -0800
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LYk07p6h3+RJ6kfx+rixaGJ0a56XPt29v7mFFbCQ+H+Gr5PjzzkrWOWfShCuKwFEIShwEz8Om7IsLjGI3hN0vw==", "comment"=>{"parent_id"=>"136", "content"=>"elmle"}, "commit"=>"Create Comment", "wad_id"=>"1"}
Wad Load (0.2ms) SELECT "wads".* FROM "wads" WHERE "wads"."id" = ? ORDER BY "wads"."created_at" DESC LIMIT ? [["id", 1], ["LIMIT", 1]]
Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE (136) LIMIT ? [["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.1ms) begin transaction
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.1ms) rollback transaction
(0.1ms) begin transaction
(0.0ms) rollback transaction
我的任何模型中都没有 attr_accessor - 只有正确定义的 has_many 和 belongs_to 关系。有人知道为什么会这样吗?
Wad 型号:
class Wad < ApplicationRecord
acts_as_votable
belongs_to :user
has_many :comments, dependent: :destroy
default_scope -> { order(created_at: :desc) }
validates :user_id, presence: true
validates :category, presence: true
validates :long_form, presence: true, length: { maximum: 1000 }
validates :short_form, presence: true, length: { maximum: 140 }
validates :problem_state, presence: true, length: { maximum: 50 }
end
评论模型:
class Comment < ApplicationRecord
acts_as_tree order: 'created_at DESC'
belongs_to :wad
belongs_to :user
end
用户模型的相关部分:
class User < ApplicationRecord
acts_as_voter
has_many :wads, dependent: :destroy
has_many :comments
据我所见,参数是:
{"comment"=>{"parent_id"=>"136", "content"=>"elmle"}, "commit"=>"Create Comment", "wad_id"=>"1"}
在这种情况下,我们将达到以下条件:
if params[:comment][:parent_id].to_i > 0
parent = Comment.find_by(params[:comment].delete(:parent_id))
@comment = parent.children.build(comment_params)
parent_id = parent.id
其中从 params["comment"]
创建的新 Comment 对象仅包含 parent_id
和 content
。
因此,正在创建没有 wad_id
键的新对象,而 belongs_to
可能需要您的模型
当您使用
Comment.find_by(params[:comment].delete(:parent_id))
您从 params[:comment] 的散列中删除了您的 :parent_id,您需要从 comment_params 中的许可中删除。尝试像这样改变你的方法,它应该有效:
def comment_params
params.require(:comment).permit(:content, :wad_id, :user_id)
end
编辑 另外我认为你需要更改
中的第一个命令parent = Comment.find_by_id(params[:comment].delete(:parent_id))
或
parent = Comment.find(params[:comment].delete(:parent_id))