title: Authorizing users on Rails 4 with CanCan based one roles in a join table
body: <p>I'm using Rails 4.0.0, ruby 2.0.0p247, and CanCan 1.6.10.</p>
  
  <p><strong>How do I authorize users with CanCan based on their role in a join table (has_many :through)?</strong></p>
  
  <p>I have 3 models: <code>User</code>, <code>Group</code>, and <code>GroupUser</code>. </p>
  
  <p>Users and Groups are associated as <code>has_many</code> through the GroupUser table. Each GroupUser also has a <code>role</code> field, which can be 'editor' or 'owner.' One group can have multiple Users, each with different roles. Also, a User can have roles in multiple Groups.</p>
  
  <p>I have the app setup with CanCan abilities, but instead of limiting access to only users with the correct role, <strong>it is authorizing <em>everybody</em></strong>.</p>
  
  <p><strong>The models</strong> are setup as follows. Also, notice that Group has a method to return a list of its owners.</p>
  
  <pre><code>class User &lt; ActiveRecord::Base
    has_many :group_users
    has_many :groups, through: :group_users
  end
  
  class Group &lt; ActiveRecord::Base
    has_many :group_users
    has_many :users, through: :group_users
  
    def owners
      User.find(self.group_users.where(role: 'owner').map(&amp;:user_id))
    end
  end
  
  class GroupUser &lt; ActiveRecord::Base
    belongs_to :user
    belongs_to :group
  end
  </code></pre>
  
  <p><strong>The CanCan ability.</strong> Notice that it uses the <code>owners</code> method on Group.</p>
  
  <pre><code>class Ability
    include CanCan::Ability
  
    def initialize(user)
  
      can :update, Group do |group|
        group.owners.include?(user)
      end
  
    end
  end
  </code></pre>
  
  <p><strong>The View</strong> is as follows. Here, users who shouldn't be able to see the link are still seeing it.</p>
  
  <pre><code>&lt;ul class="groups"&gt;
      &lt;% @groups.each do |group| %&gt;
          &lt;li&gt;
              &lt;p&gt;&lt;%= group.name %&gt;&lt;/p&gt;
              &lt;% if can? :update, Group %&gt;
                  &lt;%= link_to "Edit", edit_group_path(group) %&gt;
              &lt;% end %&gt;
          &lt;/li&gt;
      &lt;% end %&gt;
  &lt;/ul&gt;
  </code></pre>
  
  <p>Finally, the <strong>Controller action</strong> for the view is:</p>
  
  <pre><code>def index
    @groups = current_user.groups
  end
  </code></pre>
  
  <p>. . .
  One interesting thing is that even though it doesn't work during actual use, the following unit test passes:</p>
  
  <pre><code>test 'user can only update groups they own' do
    ability_one = Ability.new(users(:one)) # Owner
    ability_two = Ability.new(users(:two)) # Not-owner
  
    assert ability_one.can?(:update, groups(:one))
    assert ability_two.cannot?(:update, groups(:two))
  end
  </code></pre>