This project is archived and is in readonly mode.

#5942 ✓resolved
Fluxx

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

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

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

Comments and changes to this ticket

  • Neeraj Singh

    Neeraj Singh November 10th, 2010 @ 03:31 PM

    • Importance changed from “” to “Low”

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

  • Fluxx

    Fluxx November 10th, 2010 @ 03:55 PM

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

  • Neeraj Singh

    Neeraj Singh November 10th, 2010 @ 04:02 PM

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

  • Fluxx

    Fluxx November 10th, 2010 @ 04:53 PM

    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
    
  • Neeraj Singh

    Neeraj Singh November 11th, 2010 @ 12:58 AM

    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
    
  • Anatoliy Lysenko
  • Neeraj Singh

    Neeraj Singh November 11th, 2010 @ 04:17 PM

    • State changed from “new” to “resolved”
  • Fluxx

    Fluxx November 13th, 2010 @ 12:39 AM

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

Create your profile

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

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages