Module: ActiveRestrictor
- Defined in:
- lib/active_restrictors/active_restrictor.rb
Defined Under Namespace
Modules: ClassMethods, InstanceMethods
Class Method Summary collapse
Class Method Details
.included(klass) ⇒ Object
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/active_restrictors/active_restrictor.rb', line 223 def self.included(klass) # Patch up the model we have been called on ([klass] + klass.descendants).compact.each do |base| base.class_eval do cattr_accessor :restrictors extend ClassMethods include InstanceMethods unless(base.singleton_methods.map(&:to_sym).include?(:_restrictor_custom_user_class)) class << self # This can be overridden for customization def _restrictor_custom_user_class User end end end scope :allowed_for, lambda{|*args| user = args.detect{|item|item.is_a?(User)} if(user.present?) r_scope = user.send("allowed_#{base.name.tableize}").select("#{base.table_name}.id") r_scope.arel.ast.cores.first.projections.delete_if{|item| item != "#{base.table_name}.id"} where("#{table_name}.id IN (#{r_scope.to_sql})") else where('null') end } end end # Patch up the user to provide restricted methods ([klass._restrictor_custom_user_class] + klass._restrictor_custom_user_class.descendants).compact.each do |user_klass| user_klass.class_eval do # This patches a method onto the User instance to # provide access to the allowed instance of the model # in use. For example, if the restrictor module is # included into the Fubar model, it will # provide User#allowed_fubars define_method("allowed_#{klass.name.tableize}") do # First we perform a basic check against the User to see # if this user instance is even allowed by default user_scope = klass.restrictor_user_scoping.where(:id => self.id) if(user_scope.count > 0) scope = klass.restrictor_klass_scoping klass.full_restrictors.each do |restrictor| scope = scope.includes(restrictor[:name]) if(restrictor[:scope].present?) scope = scope.merge(restrictor[:scope].respond_to?(:call) ? restrictor[:scope].call : restrictor[:scope]) end unless(restrictor[:model_custom].present?) rtable_name = restrictor[:table_name] || restrictor[:class].table_name r_scope = self.send(restrictor[:user_association] || restrictor[:name]).scoped.select("#{rtable_name}.id") # This gives us valid joiners! # this next bit gets rid of the association_name.* rails insists upon and any extra cruft r_scope.arel.ast.cores.first.projections.delete_if{|item| item != "#{rtable_name}.id"} scope = scope.where( "#{rtable_name}.id IN (#{r_scope.to_sql})#{ " OR #{rtable_name}.id IS NULL" if restrictor[:default_allowed_all] }" ) else scope = restrictor[:model_custom].call(scope, self) end end scope else klass.where('null') end end end end end |