0

Imagine a has_many relationship for memberships for clubs:

end
class Club < ActiveRecord::Base
  has_many :memberships, :dependent => :destroy
  has_many :users, :through => :memberships
  validates :name, :is_enrollable, :presence => true
end
class Membership < ActiveRecord::Base
  belongs_to :club
end

Assume also that Club has a boolean is_enrollable field in its table. When true, a user can create a Membership associated with that Club. When false, only an admin may create the Membership record.

My question is: how do you set up CanCan's ability.rb to reflect this?

Comment: It's slightly unusual in that a field in the Club table controls the ability to create a Membership record. This cannot work:

can :create, Membership, :club => {:is_enrollable => true}

... since the Membership doesn't exist before its created. Edit: that's not true -- CanCan will work on an unsaved record before authorizing it. See answer below.

fearless_fool
  • 33,645
  • 23
  • 135
  • 217

1 Answers1

0

(I was planning on withdrawing this question since it's badly posed, but I figured out the answer and thought it might be useful.)

You CAN create a clause in Ability for :create that reads:

can :create, Membership, :club => {:is_enrollable => true}

This works because, in MembershipsController, CanCan will build a new (unsaved) Membership model and and then authorize it, effectively doing:

@membership = Membership.new(params[:membership])
raise <some error> unless Ability.new(user).can?(:create, @membership)
# if we've gotten this far, we can now save the membership
@membership.save

At least, that's what I think is going on.

fearless_fool
  • 33,645
  • 23
  • 135
  • 217