【问题标题】:App rolling back transactions and I don't know why应用程序回滚交易,我不知道为什么
【发布时间】:2019-05-31 20:01:42
【问题描述】:

我很好奇为什么我的 Rails 应用程序在没有被要求的情况下将事务回滚到 DB。

彪马日志:

Started POST "/posts" for 127.0.0.1 at 2019-01-05 00:32:32 -0500
Processing by PostsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"1AlwhyE0VY87oSyCyjmrzgxinJ7+t1TfoYYEDXvfl0pGd4DKE842KXHroFWgtXeusOgt+ZApHmB+e40qliTPjQ==", "post"=>{"title"=>"test", "category_id"=>"4", "body"=>"test"}, "commit"=>"Create Post"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 12], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:7
(0.2ms) begin transaction
↳ app/controllers/posts_controller.rb:14
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]]
↳ app/controllers/posts_controller.rb:14
(0.1ms) rollback transaction
↳ app/controllers/posts_controller.rb:14
Redirected to http://localhost:3000/posts
Completed 302 Found in 18ms (ActiveRecord: 0.8ms)

后控制器:

class PostsController < ApplicationController
  before_action :require_user

  def index
    @posts = Post.all
  end

  def new
    @post = Post.new
    @categories = Category.all
  end

  def create
    @post = Post.new(post_params)
    if @post.save(post_params)
      @post.author = current_user.username
      flash[:success] = "Post created."
      redirect_to post_path(@post.id)
    else
      flash[:danger] = "Post not created. Redirecting to main page....."
    redirect_to posts_path
  end
end

查看:

<%= form_for @post do |f| %>
<%= f.label :title, "Title of Post" %>
<%= f.text_field :title, class: "form-control" %>
<%= f.label :body, "Post Text" %>
<%= f.text_area :body, class: "form-control" %>
<%= f.submit "Create Post", class: "btn btn-info"%>
<% end %>

【问题讨论】:

  • 我们需要查看模型及其字段。
  • 要获得描述性错误消息,请将 save 替换为 save!
  • 这是因为你试图创建一个无效的帖子
  • 在您的else 分支中,登录@post.errors.full_messages 以查看您的帖子为何无法保存在数据库中
  • 您的类别 id 4 是否存在?如果没有,它会显示回滚事务。

标签: sql ruby-on-rails ruby sqlite


【解决方案1】:

您可能已经验证了author 字段的存在。由于在 create 方法中设置不正确,因此您已经回滚了事务:

class PostsController < ApplicationController

  ...

  def create
    @post = Post.new(post_params)
    if @post.save(post_params)
      @post.author = current_user.username
      flash[:success] = "Post created."
      redirect_to post_path(@post.id)

  ...
end

为了将author 分配并保存在数据库中,您需要在保存之前分配author

class PostsController < ApplicationController

  ...

  def create
    @post = Post.new(post_params)
    @post.author = current_user.username

    if @post.save(post_params)
      flash[:success] = "Post created."
      redirect_to post_path(@post.id)

  ...
end

【讨论】:

    【解决方案2】:

    根据您拥有的 Rails 版本,如果您使用的是Strong Parameters,则必须将控制器中的参数列入白名单。

    来自文档的示例:

    private
      # Using a private method to encapsulate the permissible parameters
      # is just a good pattern since you'll be able to reuse the same
      # permit list between create and update. Also, you can specialize
      # this method with per-user checking of permissible attributes.
      def person_params
        params.require(:person).permit(:name, :age)
      end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多