Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I do eager loading for multiple associations?

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
like image 435
marcamillion Avatar asked Nov 09 '22 23:11

marcamillion


1 Answers

This will hopefully be fixed in rails 5.0. There is already an issue and a pull request for it.

https://github.com/rails/rails/pull/17479

https://github.com/rails/rails/issues/8005

I have forked rails and applied the patch to 4.2-stable and it works great for me. Feel free to use it, even though I cannot guarantee to sync with upstream on a regular basis.

https://github.com/ttosch/rails/tree/4-2-stable

like image 197
tosch Avatar answered Nov 15 '22 04:11

tosch