NoMethodError(nil:NilClass 的未定义方法“posts”):app/controllers/posts_controller.rb:44:in `set_post'

NoMethodError (undefined method `posts' for nil:NilClass): app/controllers/posts_controller.rb:44:in `set_post'

我正在为 ember 博客项目构建 rails 后端。我正致力于通过 rails 验证用户操作,这样人们就无法删除他们没有删除的东西 post。在我当前的设置中,我在删除时遇到标题中显示的错误。 我已经包含了 post 控制器、它继承自的 openreadcontroller、post 的模型、评论和用户,因为它们之间的关系可能会使 "current_user" 成为 nil 值,我包含了架构,因为我总是有可能搞砸迁移或其他事情。 我怀疑在执行 destroy 方法时我无法识别用户。我有一个将 @posts 设置为 current_user.posts 的之前操作,这就是发生错误的地方。如果这确实是问题所在,我该如何识别 current_user? 在此先感谢您的帮助!

class PostsController < OpenReadController
  before_action :set_post, only: [:show, :update, :destroy]
  before_action :authenticate, only: [:create, :update, :destroy]

  # GET /posts
  def index
    @posts = Post.all

    render json: { posts: Post.all, comments: Comment.all }
  end

  # GET /posts/1
  def show
    render json: { post: @post, comments: @post.comments }
  end

  # POST /posts
  def create
    @post = current_user.posts.build(post_params)
    if @post.save
      render json: { post: @post, comments: @post.comments }, methods: :comment_ids, status: :created, location: @post
    else
      render json: @post.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /posts/1
  def update
    if @post.update(post_params)
      render json: @post
    else
      render json: @post.errors, status: :unprocessable_entity
    end
  end

  # DELETE /posts/1
  def destroy
    @post.destroy
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = current_user.posts.find(params[:id])
    end

    # Only allow a trusted parameter "white list" through.
    def post_params
      params.require(:post).permit( :title, :body)
    end
end

```

# frozen_string_literal: true
# Inherit from this class to allow unauthenticate access to read actions
class OpenReadController < ProtectedController
  READ_ACTIONS = [:index, :show].freeze
  skip_before_action :authenticate, only: READ_ACTIONS
  before_action :set_current_user, only: READ_ACTIONS
end

```

class Post < ApplicationRecord
  has_many :comments, dependent: :destroy
  belongs_to :user
end

```

# frozen_string_literal: true
class User < ApplicationRecord
  include Authentication
  has_many :posts
  has_many :comments, through: :posts
end

```

class Comment < ApplicationRecord
  belongs_to :post
end

```

ActiveRecord::Schema.define(version: 20170616000945) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "comments", force: :cascade do |t|
    t.string   "author"
    t.text     "body"
    t.integer  "post_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["post_id"], name: "index_comments_on_post_id", using: :btree
  end

  create_table "examples", force: :cascade do |t|
    t.text     "text",       null: false
    t.integer  "user_id",    null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_examples_on_user_id", using: :btree
  end

  create_table "posts", force: :cascade do |t|
    t.string   "title"
    t.text     "body"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer  "user_id"
    t.index ["user_id"], name: "index_posts_on_user_id", using: :btree
  end

  create_table "user_coins", force: :cascade do |t|
    t.string   "name"
    t.decimal  "price"
    t.integer  "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_user_coins_on_user_id", using: :btree
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",           null: false
    t.string   "token",           null: false
    t.string   "password_digest", null: false
    t.datetime "created_at",      null: false
    t.datetime "updated_at",      null: false
    t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
    t.index ["token"], name: "index_users_on_token", unique: true, using: :btree
  end

  add_foreign_key "comments", "posts"
  add_foreign_key "examples", "users"
  add_foreign_key "posts", "users"
  add_foreign_key "user_coins", "users"
end

``` 这是 chrome 控制台数据,但我不确定它是否有用。

ember.debug.js:16905 Ember Data Request DELETE 
http://localhost:4741/posts/32 returned a 500
Payload (application/json; charset=utf-8)
[object Object]
Error
    at ErrorClass.AdapterError (http://localhost:7165/assets/vendor.js:88496:16)
    at ErrorClass (http://localhost:7165/assets/vendor.js:88521:24)
    at Class.handleResponse (http://localhost:7165/assets/vendor.js:89804:22)
    at Class.handleResponse (http://localhost:7165/assets/vendor.js:73690:28)
    at Class.superWrapper [as handleResponse] (http://localhost:7165/assets/vendor.js:50205:22)
    at ajaxError (http://localhost:7165/assets/vendor.js:90169:25)
    at Class.hash.error (http://localhost:7165/assets/vendor.js:89838:23)
    at fire (http://localhost:7165/assets/vendor.js:3632:31)
    at Object.fireWith [as rejectWith] (http://localhost:7165/assets/vendor.js:3762:7)
    at done (http://localhost:7165/assets/vendor.js:9589:14)

```

这里是我的服务器日志。

    Started DELETE "/posts/32" for 127.0.0.1 at 2017-06-17 00:57:01 -0400
Processing by PostsController#destroy as HTML
  Parameters: {"id"=>"32"}
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.0ms)



NoMethodError (undefined method `posts' for nil:NilClass):

app/controllers/posts_controller.rb:44:in `set_post'

current_user 在您的 set_post 方法中为零。您没有为 OpenReadController 中的销毁操作设置 current_user。所以尝试将 before_action :set_current_user, only: READ_ACTIONS 更改为 before_action :set_current_user, except: READ_ACTIONS.

# frozen_string_literal: true
# Inherit from this class to allow unauthenticate access to read actions
class OpenReadController < ProtectedController
  READ_ACTIONS = [:index, :show].freeze
  skip_before_action :authenticate, only: READ_ACTIONS
  before_action :set_current_user, except: READ_ACTIONS
end