Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

.count on query with a .joins and a nested .includes fails

#5942

Here are our models:

class Issuance < ActiveRecord::Base
  belongs_to :issue
  belongs_to :url
end

class Issue < ActiveRecord::Base
  has_many :issuances
end

class Url < ActiveRecord::Base
  has_many :issuances
  has_one :page
end

class Page < ActiveRecord::Base
  belongs_to :url
end

If you eager-load the :url association of issuances and take the .count, everything is great:

irb(main):003:0> Issuance.joins(:issue).includes(:url).count
=> 5518

However, adding a nested .includes causes an exception:


irb(main):004:0> Issuance.joins(:issue).includes(:url => :page).count
ActiveRecord::ConfigurationError: Association named 'page' was not found; perhaps you misspelled it?
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/associations.rb:1928:in `build'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/associations.rb:1855:in `graft'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/associations.rb:1853:in `each'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/associations.rb:1853:in `graft'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation/query_methods.rb:198:in `build_joins'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation/query_methods.rb:138:in `build_arel'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation/query_methods.rb:110:in `arel'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation/calculations.rb:169:in `perform_calculation'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation/calculations.rb:152:in `calculate'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation/calculations.rb:150:in `calculate'
    from /opt/local/lib/ruby/gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation/calculations.rb:58:in `count'
    from (irb):4

Ditching the .joins makes it happy:

irb(main):007:0> Issuance.includes(:url => :page).count
=> 5518

Reported by Fluxx · November 9th, 2010 @ 10:05 PM

State: resolved
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Neeraj Singh
    Neeraj Singh
    • Importance changed from to Low

    A url has many pages or a url has one page? Could you specify that relationship?

    November 10th, 2010 @ 03:31 PM

  2. Fluxx
    Fluxx

    Url has_one :page. Sorry about forgetting to add that. I've updated the original ticket text to reflect it as well.

    November 10th, 2010 @ 03:55 PM

  3. Neeraj Singh
    Neeraj Singh

    If you don't mind can you paste migrations so that I don't need to type them. Sorry just being lazy :-)

    November 10th, 2010 @ 04:02 PM

  4. Fluxx
    Fluxx

    Here are the migrations, edited for simplicity. I haven't actually tried to run this specific code yet, so if it doesn't work let me know.

    create_table "issues", :force => true do |t|
      t.string   "name",           :limit => 100
    end
    
    create_table "issuances", :force => true do |t|
      t.integer      "crawl_id",               :null => false
      t.integer      "issue_id",               :null => false
      t.integer      "url_id",                 :null => false
    end
    
    create_table "pages", :force => true do |t|
      t.string   "title"
      t.integer  "url_id",                                   :null => false
    end
    
    create_table "urls", :force => true do |t|
      t.string   "url",                                                               :null => false
    end
    

    November 10th, 2010 @ 04:53 PM

  5. Neeraj Singh
    Neeraj Singh

    works fine for me. I used rails edge.

    ree-1.8.7-2010.02 > Issuance.joins(:issue).includes(:url).count
      SQL (0.3ms)   SELECT name
     FROM sqlite_master
     WHERE type = 'table' AND NOT name = 'sqlite_sequence'
    
      SQL (0.2ms)  SELECT COUNT(DISTINCT "issuances"."id") FROM "issuances" INNER JOIN "issues" ON "issues"."id" = "issuances"."issue_id" LEFT OUTER JOIN "urls" ON "urls"."id" = "issuances"."url_id"
     => 0 
    ree-1.8.7-2010.02 > Issuance.joins(:issue).includes(:url => :page).count
      SQL (0.4ms)  SELECT COUNT(DISTINCT "issuances"."id") FROM "issuances" INNER JOIN "issues" ON "issues"."id" = "issuances"."issue_id" LEFT OUTER JOIN "urls" ON "urls"."id" = "issuances"."url_id" LEFT OUTER JOIN "pages" ON "pages"."url_id" = "urls"."id"
     => 0 
    ree-1.8.7-2010.02 > Issuance.includes(:url => :page).count
      SQL (0.4ms)  SELECT COUNT(DISTINCT "issuances"."id") FROM "issuances" LEFT OUTER JOIN "urls" ON "urls"."id" = "issuances"."url_id" LEFT OUTER JOIN "pages" ON "pages"."url_id" = "urls"."id"
     => 0
    

    November 11th, 2010 @ 12:58 AM

  6. Anatoliy Lysenko
  7. Neeraj Singh
    Neeraj Singh
    • State changed from new to resolved

    November 11th, 2010 @ 04:17 PM

  8. Fluxx
    Fluxx

    Just verified the fix for the previous bug running HEAD for 3-0-stable. Thanks guys.

    November 13th, 2010 @ 12:39 AM