vendredi 16 juin 2017

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

I'm building a rails backend for an ember blog project. I'm working on authenticating user actions via rails so people can't delete things they didn't post. With my current setup I'm getting the error you see in the title when I go to delete. I've included the post controller, the openreadcontroller that it inherits from, the models for posts, comments and users, because the relationships between them might be making "current_user" a nil value, and I included the schema, because there's always a chance I bungled a migration or something. I suspect I'm failing to identify the user when it comes time to execute the destroy method. I have a before action that sets the @posts to current_user.posts and this is where the error occurs. If this is indeed the issue, how do I identify current_user? Thanks in advance for the help!

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

``` Here is the chrome console data, though I'm not sure it's useful.

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)

```

And here for good measure is my server log.

    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'




Aucun commentaire:

Enregistrer un commentaire