nqtien310
nqtien310

Reputation: 359

Rails 3 ActiveRecord#includes bug?

I have the following models

class Account < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  attr_accessible :email
  has_many :accounts
end

As far as i know, in order to select all accounts that for all users with email match a pattern, we must do a join

Account.joins(:user).where("users.email ILIKE ?", '%pattern%') -> work

And here comes the magic, replacing includes with joins, still work like a charm

Account.includes(:user).where("users.email ILIKE ?", '%pattern%') -> work

But

Account.includes(:user).where("users.email ILIKE ?", '%pattern%').count -> error

Any explanation ? isn't includes just for Eager Loading only ?

Upvotes: 1

Views: 73

Answers (1)

Slava.K
Slava.K

Reputation: 3080

Because without explicit reference includes loads relation in a separate query. Take a look at rails console:

[11] pry(main)> Account.includes(:user)
  AccountsUser Load (4.6ms)  SELECT "accounts".* FROM "accounts"
  User Load (11.7ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (...

[11] pry(main)> Account.includes(:user).where("users.email ILIKE ?", '%pattern%').to_sql
  SELECT "accounts".* FROM "accounts" WHERE (users.email ILIKE '%admin%')

That is why you are getting an error - users table is not referenced in a query. To reference users table use either references or eager_load:

Account.includes(:user).references(:users).where("users.email ILIKE ?", '%pattern%').count

or

Account.eager_load(:user).where("users.email ILIKE ?", '%pattern%').count

Note that includes works with association names while references needs the actual table name

Upvotes: 1

Related Questions