I am using public_activity and one of my partials I have this call:
<%= link_to "#{activity.trackable.user.name} " + "commented on " + "#{activity.trackable.node.name}", node_path(activity.trackable.node.family_tree_id,activity.trackable.node) %>
That is executed by this call:
<% @unread_act.each do |friend| %>
<li><%= render_activity friend %> </li>
<% end %>
That instance variable is assigned in my ApplicationController
here:
before_filter :handle_nofications
def handle_nofications
if current_user.present?
@unread_act = Notification.where(owner_id: current_user).includes(:trackable => :user).unread_by(current_user)
end
end
I am using the gem Bullet, to find N+1 queries and the feedback I get is this:
N+1 Query detected
Comment => [:node]
Add to your finder: :include => [:node]
N+1 Query method call stack
I initially got that message for :trackable
and for :user
. Both of which I am now eager loading via includes
within that assignment statement.
However, I have no idea how to go 3 levels deep on an eager loading - rather than just two.
Given that the node is called like activity.trackable.node.name
, I imagine some appropriate eager loading assignment would look something like:
@unread_act = Notification.where(owner_id: current_user).includes(:trackable => [:user, :node]).unread_by(current_user)
But the error I get is this:
ActiveRecord::AssociationNotFoundError at /
Association named 'node' was not found on Node; perhaps you misspelled it?
I even get that when I simply do:
@unread_act = Notification.where(owner_id: current_user).includes(:trackable => :node).unread_by(current_user)
So I suspect something else is going wrong here.
Any ideas?
Edit 1
See Node & Notification models and associations below.
Node.rb
class Node < ActiveRecord::Base
include PublicActivity::Model
tracked except: :update, owner: ->(controller, model) { controller && controller.current_user }
belongs_to :family_tree
belongs_to :user
belongs_to :media, polymorphic: true, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :node_comments, dependent: :destroy
Notification.rb
class Notification < PublicActivity::Activity
acts_as_readable :on => :created_at
end
It seems the correct way to approach this is by using an array on the trackable
attribute like so:
@unread_act = Notification.where(recipient_id: current_user).includes(:trackable => [:user, :node]).unread_by(current_user).order("created_at desc")
The main part is:
includes(:trackable => [:user, :node])
This seems to have worked beautifully.