Is it possible to define abilities in separate file and include them in ability.rb file inside initialize method ?
belowed code returns: tried and got: undefined method 'can'
ability.rb
def initialize(user)
include MyExtension::Something::CustomAbilities
...
end
lib/my_extension/something.rb
module MyExtension::Something
module CustomAbilities
can :do_it, Project do |project|
check_something_here and return true or false...
end
end
end
perfect solution, if possible, would be to extend class Ability with Ability.send :include/extend, so without explicit include in initialize method
Just Include the Module and Call the Method in initialize
The trick here is to create modules for each of your abilities, include them in your base ability.rb
file and then run the specific method in your initialize
method, like so:
In your ability.rb
file:
class Ability
include CanCan::Ability
include ProjectAbilities
def initialize user
# Your "base" abilities are defined here.
project_abilities user
end
end
In your lib/project_abilities.rb
file:
module ProjectAbilities
def project_abilities user
# New abilities go here and later get added to the initialize method
# of the base Ability class.
can :read, Project do |project|
user.can? :read, project.client || user.is_an_admin?
end
end
end
Using this pattern, you can break out your abilities into various modules (perhaps, one for each model that you have to define user abilities for).
Take a Look at Pundit
Also of note, take a look at the (relatively) new gem called Pundit, which provides a much more scalable pattern for authorization of larger sites.
Cheers,
JP
With more modern Rubies, you can achieve this with prepend
module CashBalance
attr_accessor :balance
def deposit(amount)
self.balance += amount
end
def withdraw(amount)
self.balance -= amount
end
def initialize(*args)
self.balance = 0.0
super
end
end
class Bank
prepend CashBalance
def initialize(name)
@name = name
end
def dump
puts "%s has a balance of %0.2f" % [ @name, balance ]
end
end
b = Bank.new("Fleet")
b.deposit(20)
b.dump
b.withdraw(10)
b.dump
yields
$ ruby blarg.rb
Fleet has a balance of 20.00
Fleet has a balance of 10.00