Reputation:
I need the current user to see only his own todo list after login. (Using Devise) And I got error "Undefined method "lists" for nil:NilClass. I made changes in the User model (has_many :lists), as well in the List model (belongs_to :user). I got an error undefined method `lists' for nil:NilClass
Lists Controller code is
class ListsController < ApplicationController
before_action :authenticate_user!, except: [:index]
def index
@lists = current_user.lists.order('created_at') <----- error occurs here
end
def new
@list = current_user.lists.new
end
def create
@list = current_user.lists.new list_params
@list.save
redirect_to lists_path
end
def edit
@list = List.find params[:id]
end
def update
@list = List.find params[:id]
@list.update list_params
redirect_to lists_path
end
def destroy
@list = List.find params[:id]
@list.destroy
redirect_to lists_path
end
private
def list_params
params.require(:list).permit(:title)
end
end
schema.rb code
ActiveRecord::Schema.define(version: 2020_05_10_131407) do
create_table "lists", force: :cascade do |t|
t.string "title"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "user_id"
end
create_table "tasks", force: :cascade do |t|
t.string "title"
t.boolean "completed"
t.integer "list_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["list_id"], name: "index_tasks_on_list_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
And Index.html code if need
<div class="col-md-12">
<h1>ToDo List</h1>
<div class="buffer-top"><%= link_to "New List", new_list_path, class: 'btn btn-primary' %></div>
<div class="buffer-top">
<% @lists.each do |list| %>
<%= render partial: 'list', object: list %>
<% end %>
</div>
</div>
Upvotes: 0
Views: 54
Reputation: 3002
You are not authenticating the User for the index view, the error is because there is no current_user
, so you are calling the method lists
on nil
.
You should check if there is a user first
def index
if user_signed_in?
@lists = current_user.lists.order('created_at')
else
<!-- Do somthing here, what do you want if no user is there? -->
end
end
Not exactly sure what you would want if there is no user so you'll have to fill that part in. The issue really here is you are basically creating a view where you want a user, but you also do not require a user, the user's @lists
would likely be better served on a different view if you do not want to require a user here.
You will also have to fix the view to check as well.
<% if user_signed_in? %>
<div class="buffer-top">
<% @lists.each do |list| %>
<%= render partial: 'list', object: list %>
<% end %>
</div>
<% end %>
If you really want to go with this setup then you could DRY it up by removing the lines inside the index
method and changing the view.
<% if user_signed_in? %>
<div class="buffer-top">
<% current_user.lists.order('created_at').each do |list| %>
<%= render partial: 'list', object: list %>
<% end %>
</div>
<% end %>
Upvotes: 1