salsify/goldiloader

It eager-loaded the AR::Relation when calling `==` method

Closed this issue · 5 comments

I recently had trouble with unexpected eager-loading. I have something like this:

class Post < ActiveRecord::Base
  belongs_to :user
  scope :rank, -> {
    # do some ranking..
  }
end

class User < ActiveRecord::Base
  has_many :posts, dependent: :destroy
end
def filter_scope(scope)
  scope = scope.rank if scope == Post || (scope.is_a?(ActiveRecord::Relation) && scope.klass == Post)
  # ...
  scope
end

filter_scope(user.posts)

The expected result of filter_scope is an ActiveRecord::Relation object and it should not execute any queries. However, it triggered the query at the line scope = scope.rank if scope == Post:

SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (?)

If I change the variables position, the problem goes away:

scope = scope.rank if Post == scope #...
# Or also work with this:
scope = scope.rank if scope.equal?(Post) # ...

And if I disable Goldiloader, the problem also does not happen.
FYI, I'm using Rails 4.2.4.

Thanks for filing the issue. I'll take a look.

@kidlab - I wasn't able to reproduce this problem. A gist with a test case based on your description can be found here. Can you take a look and see if you can come up with a reproducible test case?

Sorry @jturkel the real code actually uses an AR association filter_scope(user.posts). I updated the description. You might be able to reproduce the problem now.

I double-checked the problem, looks like it's a nature of Rails when we perform == on an ActiveRecord::Associations::CollectionProxy within any kinds of objects, it will try to load the collection firstly, then compares these objects.

user.posts == nil # => Load user's posts
nil == user.posts # => Won't load user's posts.

Interestingly that it does not happen with an ActiveRecord::Relation:

Post.where(user_id: user.id) == nil # => Won't load the posts

So, this does not belong to Goldiloader. I'm sorry for my mistake, thank you for your time @jturkel. We should close this issue :)

No worries. Glad it didn't turn out to be a Goldiloader issue :)