MaxLeoTony
MaxLeoTony

Reputation: 67

undefined method `notifications' for nil:NilClass

I'm displaying notifications in the navbar, and it works on about half of the pages. On the other half, I get a nil:NilClass error, which I've dealt with before. But I'm under the impression that @current_user.notifications.each is enough because of the user and notification model. Apparently not.

Navbar section with notifications

<div class="dropdown nav-button notifications-button hidden-sm-down">
    <a class="btn btn-secondary dropdown-toggle" href="#" id="notifications-dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      <i id="notificationsIcon" class="fa fa-bell-o" aria-hidden="true"></i>
    </a>
    <div class="dropdown-menu notification-dropdown-menu" aria-labelledby="notifications-dropdown">
      <h6 class="dropdown-header">Notifications</h6>
      <div id="notificationsContainer" class="notifications-container">
        <% @current_user.notifications.each do |notification| %>
            <% if notification.notice_type == "post" %>
              <%= link_to "Someone commented on your post", notification.post %>
            <% end %>
          <br>
        <% end %>
        <hr>
      <%= link_to "All Notifications", notifications_path %>
      <br>
      <br>
    </div>
  </div>
</div>

User Model includes

has_many :notifications, dependent: :destroy

Notification Model

class Notification < ApplicationRecord
  belongs_to :notified_by, class_name: 'User'
  belongs_to :user
  belongs_to :post, optional: true
  validates :user_id,
            :notified_by_id,
            :identifier,
            :notice_type,
            presence: true
end

I worked with this tutorial (https://www.devwalks.com/lets-build-instagram-part-6-notifications/) but changed some things along the way. for example, I didn't want to use HAML. Anyways, why isn't it recognizing the current_user, I'm sure I have to define it which is strange because it works everywhere else.

Upvotes: 0

Views: 379

Answers (1)

jvillian
jvillian

Reputation: 20263

You need to set the @current_user variable every time you want to render your navbar. Just because you have a User model does not mean that the @current_user variable has any value at any particular point in time. That's your job to set the variable. Rails is clever, but not that clever.

Typically, you'll set the @current_user variable in the controller. Some people like to do a before_action for that sort of thing. Personally, I do not. You can set your before_action in your ApplicationController and then your @current_user variable will be available everywhere.

In Rails 4, that might look something like:

class ApplicationController < ActionController::Base
  before_action :set_user

  def index()     do_action_with_presentation             end
  def new()       do_action_with_presentation             end
  def create()    do_cancellable_action_with_redirect     end
  def show()      do_action_with_presentation             end
  def edit()      do_action_with_presentation             end
  def update()    do_action_with_presentation             end
  def delete()    do_action_with_presentation             end

private

  def set_user
    @current_user = User.find_by(something: :clever)
  end

end

You can ignore my peculiar REST actions. They're, um, peculiar.

Upvotes: 1

Related Questions