Topic: Controller module constants (dynamic class loading)
I'm developing a content management system at the moment that bases its permission system on the controllers, actions and IDs of the Rails structure. As such, rather than having to keep my own list of all the controllers and actions in my app, I wrote the below code to automate it:
@controllers = []
@cs = ['Choose a controller']
cs = Dir.entries(RAILS_ROOT + '/app/controllers')
for ctrl in cs
# check for sub-folders
if ctrl !~ /[a-z]*\.[a-z]*/
subs = Dir.entries(RAILS_ROOT + '/app/controllers/' + ctrl)
for file in subs
file = file.sub(/([a-z])/) {|match| match.upcase}
file = file.gsub(/_([a-z])/) {|match| match.upcase.sub(/_/, '')}
file = file.sub(/.rb/, '')
if !['.', '..', 'Application'].include? file
# add module
file = ctrl.sub(/([a-z])/) {|match| match.upcase} + '::' + file
c = Object.const_get(file.gsub(/::/, '')).new
@cs << c.controller_name
@controllers << {
:name => c.controller_name,
:methods => c.send(:action_methods).map(&:to_s)
}
end
end
next
end
ctrl = ctrl.sub(/([a-z])/) {|match| match.upcase}
ctrl = ctrl.gsub(/_([a-z])/) {|match| match.upcase.sub(/_/, '')}
ctrl = ctrl.sub(/.rb/, '')if !['.', '..', 'Application'].include? ctrl
c = Object.const_get(ctrl).new
@cs << c.controller_name
@controllers << {
:name => c.controller_name,
:methods => c.send(:action_methods).map(&:to_s)
}
end
end
This has been working fine (though I imagine there may be a cleaner/more efficient way of doing it, so feel free to point out if there is - I'm still learning Ruby/Rails) until I added a module controller Manage::Users and this line broke:
c = Object.const_get(ctrl).new
This is the line that instantiates each controller to then get its actions, though for modules I get this error:
uninitialized constant Manage::UsersController
And so I eventually get to my question: how are 'sub-controllers' named as constants (if they are) or is there a better way of creating new instances of classes where the class name is a variable?
Any suggestions are much appreciated!