Skip to content

Cannot determine SQL conditions or joins from block for :index on a resource #130

Closed
tamoyal opened this Issue Aug 23, 2010 · 5 comments

2 participants

@tamoyal
tamoyal commented Aug 23, 2010

I have a Product model and controller. My index method looks like this:


def index
@req_host_w_port = request.host_with_port
logger.info "current_ability = #{current_ability.inspect}"
@products = Product.accessible_by(current_ability, :index)
end

I get an error when I try to retrieve the products there. My ability class for product looks like this:


can :index, Product do |product|
product && !(product.approved_at.nil?)
end

And the error looks like this:


Cannot determine SQL conditions or joins from block for :index Product(id: integer, secret: string, context_date: datetime, expiration_date: datetime, blurb: text, created_at: datetime, updated_at: datetime, owner_id: integer, product_type_id: integer, approved_at: datetime)

I'm not really sure why this is happening because it seems like a very simple example, but I've seen some weirdness occur with can blocks, so maybe that's where the issue lies.

@tamoyal
tamoyal commented Aug 23, 2010

To elaborate on this issue, the following two pieces of code are not equivalent even though they seem like they should be. The top piece works whereas the bottom piece throws an error:

can :index, Product, :approved_at => nil


can :index, Product do |product|
    product && product.approved_at.nil?
end


cancan (1.3.2) lib/cancan/ability.rb:219:in `relevant_can_definitions_for_query'
cancan (1.3.2) lib/cancan/ability.rb:217:in `each'
cancan (1.3.2) lib/cancan/ability.rb:217:in `relevant_can_definitions_for_query'
cancan (1.3.2) lib/cancan/ability.rb:189:in `query'
cancan (1.3.2) lib/cancan/active_record_additions.rb:23:in `accessible_by'
app/controllers/products_controller.rb:12:in `index'
actionpack (3.0.0.beta4) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.0.0.beta4) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.0.0.beta4) lib/abstract_controller/base.rb:145:in `process_action'
actionpack (3.0.0.beta4) lib/action_controller/metal/rendering.rb:11:in `process_action'
actionpack (3.0.0.beta4) lib/abstract_controller/callbacks.rb:18:in `process_action'
activesupport (3.0.0.beta4) lib/active_support/callbacks.rb:438:in `_run__1118320962__process_action__199225275__callbacks'
activesupport (3.0.0.beta4) lib/active_support/callbacks.rb:408:in `send'
activesupport (3.0.0.beta4) lib/active_support/callbacks.rb:408:in `_run_process_action_callbacks'
activesupport (3.0.0.beta4) lib/active_support/callbacks.rb:88:in `send'
activesupport (3.0.0.beta4) lib/active_support/callbacks.rb:88:in `run_callbacks'
actionpack (3.0.0.beta4) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.0.0.beta4) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
activesupport (3.0.0.beta4) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (3.0.0.beta4) lib/active_support/notifications.rb:48:in `__send__'
activesupport (3.0.0.beta4) lib/active_support/notifications.rb:48:in `instrument'
actionpack (3.0.0.beta4) lib/action_controller/metal/instrumentation.rb:28:in `process_action'
actionpack (3.0.0.beta4) lib/action_controller/metal/rescue.rb:8:in `process_action'
actionpack (3.0.0.beta4) lib/abstract_controller/base.rb:114:in `process'
actionpack (3.0.0.beta4) lib/abstract_controller/rendering.rb:40:in `process'
actionpack (3.0.0.beta4) lib/action_controller/metal.rb:126:in `dispatch'
actionpack (3.0.0.beta4) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.0.0.beta4) lib/action_controller/metal.rb:166:in `action'
actionpack (3.0.0.beta4) lib/action_dispatch/routing/route_set.rb:27:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/routing/route_set.rb:27:in `call'
rack-mount (0.6.10) lib/rack/mount/route_set.rb:148:in `call'
rack-mount (0.6.10) lib/rack/mount/code_generation.rb:89:in `recognize'
rack-mount (0.6.10) lib/rack/mount/code_generation.rb:66:in `optimized_each'
rack-mount (0.6.10) lib/rack/mount/code_generation.rb:88:in `recognize'
rack-mount (0.6.10) lib/rack/mount/route_set.rb:139:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/routing/route_set.rb:457:in `call'
warden (0.10.7) lib/warden/manager.rb:35:in `call'
warden (0.10.7) lib/warden/manager.rb:34:in `catch'
warden (0.10.7) lib/warden/manager.rb:34:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/head.rb:14:in `call'
rack (1.1.0) lib/rack/methodoverride.rb:24:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/flash.rb:177:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/session/abstract_store.rb:106:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/cookies.rb:235:in `call'
activerecord (3.0.0.beta4) lib/active_record/query_cache.rb:31:in `call'
activerecord (3.0.0.beta4) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in `cache'
activerecord (3.0.0.beta4) lib/active_record/query_cache.rb:11:in `cache'
activerecord (3.0.0.beta4) lib/active_record/query_cache.rb:30:in `call'
activerecord (3.0.0.beta4) lib/active_record/connection_adapters/abstract/connection_pool.rb:365:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/callbacks.rb:46:in `call'
activesupport (3.0.0.beta4) lib/active_support/callbacks.rb:414:in `_run_call_callbacks'
activesupport (3.0.0.beta4) lib/active_support/callbacks.rb:88:in `send'
activesupport (3.0.0.beta4) lib/active_support/callbacks.rb:88:in `run_callbacks'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/callbacks.rb:44:in `call'
rack (1.1.0) lib/rack/sendfile.rb:105:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/show_exceptions.rb:48:in `call'
railties (3.0.0.beta4) lib/rails/rack/logger.rb:14:in `call'
rack (1.1.0) lib/rack/runtime.rb:17:in `call'
activesupport (3.0.0.beta4) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.1.0) lib/rack/lock.rb:11:in `call'
rack (1.1.0) lib/rack/lock.rb:11:in `synchronize'
rack (1.1.0) lib/rack/lock.rb:11:in `call'
actionpack (3.0.0.beta4) lib/action_dispatch/middleware/static.rb:30:in `call'
railties (3.0.0.beta4) lib/rails/application.rb:145:in `call'
railties (3.0.0.beta4) lib/rails/application.rb:81:in `send'
railties (3.0.0.beta4) lib/rails/application.rb:81:in `method_missing'
railties (3.0.0.beta4) lib/rails/rack/log_tailer.rb:15:in `call'
rack (1.1.0) lib/rack/content_length.rb:13:in `call'
rack (1.1.0) lib/rack/handler/webrick.rb:48:in `service'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
rack (1.1.0) lib/rack/handler/webrick.rb:14:in `run'
rack (1.1.0) lib/rack/server.rb:155:in `start'
railties (3.0.0.beta4) lib/rails/commands/server.rb:62:in `start'
railties (3.0.0.beta4) lib/rails/commands.rb:30
railties (3.0.0.beta4) lib/rails/commands.rb:27:in `tap'
railties (3.0.0.beta4) lib/rails/commands.rb:27
script/rails:6:in `require'
script/rails:6

@tamoyal
tamoyal commented Aug 24, 2010

After some more tracing I found where the issue exists but I'm not quite sure if this is an actual bug or if I am doing something wrong. Seems like a bug, though. In CanCan's ability class implementation, this function grabs the can definitions for a query:


def relevant_can_definitions_for_query(action, subject)
relevant_can_definitions(action, subject).each do |can_definition|
if can_definition.only_block?
raise Error, "Cannot determine SQL conditions or joins from block for #{action.inspect} #{subject.inspect}"
end
end
end

The only_block? function returns true if a can definition has a block but no conditions. After looking at how a can definition is initialized, this doesn't make much sense to me. The example in the README (see below) has a block but no conditions, however it is supposed to work correctly.

can :update, Project do |project|
project && project.groups.include?(user.group)
end

@tamoyal
tamoyal commented Aug 24, 2010

This is not a bug, it's a limitation of the library. See the answer to this question:
http://stackoverflow.com/questions/3557091/using-blocks-to-define-abilities-in-cancan-raises-an-exception/3557445#3557445

@ryanb
Owner
ryanb commented Aug 30, 2010

I'll update the readme to make this a bit more clear. Sorry for the confusion.

@ryanb
Owner
ryanb commented Aug 30, 2010

be more clear about blocks not working with accessible_by - closed by 4fe44af

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.