Skip to content

Problem using accessible_by with a belongs_to relation #905

exklamationmark opened this Issue Jul 22, 2013 · 5 comments

2 participants



I got a problem where the call to accessible_by returns empty, while checking the permission using current_ability.can? show that I can access to the object. The details are here



ruby '1.9.3'
gem 'rails', '3.2.13'
gem 'devise', '~> 2.2.4'
gem 'cancan', '~> 1.6.10'

SubscriptionAssignment model

class SubscriptionAssignment < ActiveRecord::Base
  attr_accessible :active, :child_id, :subscription_id

  belongs_to :child, :class_name => "User"
  belongs_to :subscription
  has_one :section, :through => :subscription


class Subscription < ActiveRecord::Base
  attr_accessible :quota, :section_id, :user_id

  belongs_to :user
  belongs_to :section
  has_many :subscription_assignments


class Ability
  include CanCan::Ability

  def initialize(user)

    if user
      if user.role == 'admin'
        return admin_permission
      elsif user.role == 'parent'
        return parent_permission(user)
      elsif user.role == 'child'
        return child_permission(user)

    # all other casese
    return guest_permission

  def parent_permission(user)
    can [:index, :show, :update, :destroy], Subscription, :user_id =>
    can [:create], Subscription
    can [:destroy, :show, :update], SubscriptionAssignment, subscription: {:user_id =>}
    can [:create], SubscriptionAssignment



=> [#<Subscription id: 1, user_id: 1, section_id: 110, quota: 1, created_at: "2013-07-22 02:19:58", updated_at: "2013-07-22 02:19:58">,
 #<Subscription id: 2, user_id: 4, section_id: 110, quota: 1, created_at: "2013-07-22 02:21:09", updated_at: "2013-07-22 02:21:48">]
=> [#<SubscriptionAssignment id: 1, child_id: 2, subscription_id: 1, active: true, created_at: "2013-07-22 02:19:58", updated_at: "2013-07-22 02:19:58">,
 #<SubscriptionAssignment id: 2, child_id: 5, subscription_id: 2, active: true, created_at: "2013-07-22 02:21:48", updated_at: "2013-07-22 02:21:48">]
=> #<Ability:0x00000006597d50
 @aliased_actions={:read=>[:index, :show], :create=>[:new], :update=>[:edit]},
    @actions=[:index, :show, :update, :destroy],
    @expanded_actions=[:index, :show, :update, :edit, :destroy],
     [Subscription(id: integer, user_id: integer, section_id: integer, quota: integer, created_at: datetime, updated_at: datetime)]>,
    @expanded_actions=[:create, :new],
     [Subscription(id: integer, user_id: integer, section_id: integer, quota: integer, created_at: datetime, updated_at: datetime)]>,
    @actions=[:destroy, :show, :update],
    @expanded_actions=[:destroy, :show, :update, :edit],
     [SubscriptionAssignment(id: integer, child_id: integer, subscription_id: integer, active: boolean, created_at: datetime, updated_at: datetime)]>]>
current_ability.can? :update, SubscriptionAssignment.find(1) => true
current_ability.can? :update, SubscriptionAssignment.find(2) => false
SubscriptionAssignment.accessible_by(current_ability) => []
SubscriptionAssignment.accessible_by(current_ability).to_sql => "SELECT \"subscription_assignments\".* FROM \"subscription_assignments\"  WHERE ('t'='f')"

I am not sure why the SQL query doesn't have an INNER JOIN. It would be great if you can give me an idea :) Thanks


Interesting problem! It turns out accessible_by takes a second optional argument, the action, which defaults to :index. See model_additions.rb.

def accessible_by(ability, action = :index)
  ability.model_adapter(self, action).database_records

Your current_ability for SubscriptionAssignment allows :show but not :index. None of your can rules matches, so I assume that's why the SQL contains the contradiction WHERE ('t'='f').

For future questions, please remember that github issues are for bugs or suggested features. Questions about usage are more appropriate on


Thanks, Jared!

I 'll put the question to SO then.


Ummm, you can do that if you want to .. but I already answered it, didn't I?


True, I was thinking of putting it as a self-answered question just for sharing the info.

I ended up fixing it with something like this

can [:read, :update, :destroy], SubscriptionAssignment, subscription: {:user_id =>}

Cool. I'm glad I could help. Please close this issue.

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.