Search code examples
ruby-on-railscancancancancan

Rails / Cancan - load resources through association


I have these models:

Company 
  has_many :users
  has_many :accounts

User
  belongs_to :company

Account
  belongs_to :company

Users should have access to certain resources through their company, and I'd like to implicitly load those with Cancan:

class AccountsController < ApplicationController
  load_resource # Cancan doesn't know how to load through the user's company

I can obviously do this explicitly:

class AccountsController
  def index
    @accounts = current_user.company.accounts
  end

But this seems like unnecessary code and I suspect there's already a pattern for this.

I see that Cancan has the ability to define a through on the current user:

class AccountsController
  load_resource through: :current_user

But that will call current_user.accounts - that's invalid because accounts belong to companies, not to users. I could defer the accounts call from User to Company, but that seems like a hack.

I also tried passing in a string:

class AccountsController
  load_resource through: 'current_user.company'

And that gave me '@current_user.company' is not allowed as an instance variable name

I did some Googling but couldn't find it. Any help?


Solution

  • Try something like this:

    class AccountsController
      load_resource :company, through: :current_user, singleton: true
      load_resource through: :company
    end
    

    In your example, I believe you already have this in @accounts = current_user.company.accounts. Using cancan's load_resource to load the company, then the account should result in a similar set of queries.