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
我正在为 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