Skip to content
This repository

load_collection? triggers sql query on inherited resources #813

Open
wants to merge 1 commit into from

4 participants

Toms Mikoss Nate Bird Peter Fern Matt Glover
Toms Mikoss

When resource_base is a ActiveRecord::Associations::CollectionProxy (common case - inherited resources) resource_base.respond_to? will actually execute the query, due to it being overwritten here.

This presents a problem when working with big data sets + pagination, since all the records will be loaded in memory regardless of how the collection is paginated afterwards.

Rails version: 3.2.11
CanCan version: 1.6.8

Toms Mikoss

Will need some version-dependent guards around this code, since the referenced code is different prior to 3.1, and has changed again in current master.

Toms Mikoss

This should fix #398

Nate Bird

Can you write up a pull request for the different versions of Rails? Then Ryan can nail down a fix for various versions and decide CanCan v.x will support which implementations or if we can to handle the version cases inline.

Matt Glover matt-glover commented on the diff
lib/cancan/controller_resource.rb
@@ -74,7 +74,11 @@ def load_instance?
74 74
     end
75 75
 
76 76
     def load_collection?
77  
-      resource_base.respond_to?(:accessible_by) && !current_ability.has_block?(authorization_action, resource_class)
  77
+      if @options[:through]
1

Does this need to be something like: if @options[:through] && parent_resource instead to avoid raising when resource_base resolves to the resource_class when @options[:shallow] is true?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Peter Fern

I like the end.method syntax better here because it avoids duplication, but I think simply checking for resource_base.respond_to? :proxy_association as I did in #729 is the right way of fixing this. I've been using that in production for about a year.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 5 additions and 1 deletion. Show diff stats Hide diff stats

  1. 6  lib/cancan/controller_resource.rb
6  lib/cancan/controller_resource.rb
@@ -74,7 +74,11 @@ def load_instance?
74 74
     end
75 75
 
76 76
     def load_collection?
77  
-      resource_base.respond_to?(:accessible_by) && !current_ability.has_block?(authorization_action, resource_class)
  77
+      if @options[:through]
  78
+        resource_base.proxy_association.klass
  79
+      else
  80
+        resource_base
  81
+      end.respond_to?(:accessible_by) && !current_ability.has_block?(authorization_action, resource_class)
78 82
     end
79 83
 
80 84
     def load_collection
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.