#18 ✓resolved
Wade Winningham

will_paginate ignores the :include with has_many

Reported by Wade Winningham | June 27th, 2007 @ 11:50 AM

I setup a paginate for a has_many relationship that has an :include piece to it. Some of the conditions rely on the included tables and will_paginate was not using them.


class Producer < ActiveRecord::Base
  has_many :active_cases, :class_name => "Case", :include => [:employer => :carrier], :conditions => "employers.date_cancelled IS NULL"

class ProducersController < ApplicationController
  def show
    @producer = Producer.find(params[:id])
    @active_cases, @page = @producer.active_cases.paginate(
        :page => params[:page],
        :order => "employers.name",
        :per_page => 10

The above code gives me an error on the "employers.name" column.


Add the appropriate :include along with the call to paginate. This makes things work, but not very DRY.

Comments and changes to this ticket

  • Mislav

    Mislav June 27th, 2007 @ 11:50 AM

    • State changed from “new” to “open”
    • Assigned user changed from “Chris Wanstrath” to “Mislav”

    Hmm I need to investigate is pagination really possible with eager loading because it relies on SQL limit and offset.

    Thanks for the report. BTW, your example uses the old-style call to "paginate". In the new version of will_paginate only one argument is returned: the collection. Current page is saved internally.

  • Jonathan del Strother
  • Jonathan del Strother

    Jonathan del Strother June 27th, 2007 @ 11:50 AM

    FWIW, we've had good results with something like this :

    class ActiveRecord::Associations::AssociationCollection
      include WillPaginate::Finder::ClassMethods
      alias_method_chain :method_missing, :paginate

    The only problem with mixing WillPaginate into rails' associations is that you have to be really careful with missing methods. For instance, 'returning' (used at the end of method_missing_with_paginate) is undefined from association_proxy.rb:8. This then prompts a load_target, *loading your entire collection*, before 'returning' is forwarded on to the loaded collection.

    After replacing the returning block with the non-K-combinator equivalent, it all seems to work great.

  • Chris Wanstrath

    Chris Wanstrath June 27th, 2007 @ 11:50 AM

    • State changed from “open” to “resolved”

    (from [278]) Will Paginate: make the finders apply to association proxies, also. This fixes the issues you could be having when doing something like user.projects.paginate() with conditions or eager loading. [Jon] [#18 state:resolved]


  • Mislav

    Mislav June 27th, 2007 @ 11:50 AM

    Thanks Jon. However, I didn't remove the K combinator yet. Can you explain why prompting the load target for "returning" makes the entire collection load?

    Any tips on how can I inspect AssociationProxy (and subclasses) instances to see exactly what gets loaded and when? (Think of this as a generic Rails question.)

  • Jonathan del Strother

    Jonathan del Strother June 27th, 2007 @ 11:50 AM

    It's kinda a total pain, actually - I spent the entire morning in ruby-debug, trying to figure out why Rails was trying to load my entire table rather than just a single page.

    First, the association proxy has had 90% of the usual methods removed (see association_proxy.rb:8). This includes 'returning'. So, calling returning will end up at method_missing on the proxy (association_proxy.rb:127), which calls load_target, which loads your entire collection (scoped by whatever has_many parameters you've defined), before forwarding 'returning' onto the loaded collection. The real collection still has the 'returning' method from misc:rb, and so it executes as expected.

    The transparency of the proxy made this a little difficult to track down. For instance, calling respond_to?(:returning) returns true, since respond_to? is no longer defined on the proxy and it forwards on to the load target. It took me a while to figure out why 'debugger' was prompting method_missing - again, it's forwarding through to the target.

    As for tracking what gets loaded when... printing sql to stdout when you're in the console is handy (http://weblog.jamisbuck.org/2007...), as is the query_trace plugin (https://terralien.devguard.com/s...)

  • Mislav

    Mislav June 27th, 2007 @ 11:50 AM

    So what do you think of [280] then?

  • Jonathan del Strother

    Jonathan del Strother June 27th, 2007 @ 11:50 AM

    Ah, hadn't thought of just calling Object.returning directly. Seems to work nicely.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

Everyone's favorite Ruby library for pagination of practically anything!

People watching this ticket

Referenced by