Reputation: 15056
I am currently writing a Rails engine, and I wanted to make its ApplicationController
descend from the controller specified in the engine's config.
For example, I have in lib/my_engine.rb
the following:
module MyEngine
mattr_accessor :authenticated_controller
class << self
def authenticated_controller
@@authenticated_controller.constantize
end
end
end
In app/controllers/my_engine/application_controller.rb
, I have:
class MyEngine::ApplicationController < MyEngine.authenticated_controller
#some code
end
And in my app's initializer, I set MyEngine.authenticated_controller = 'AuthenticatedController'
.
This allows me to keep my engine mostly ignorant of the authentication engine, as now all my engine requires is some controller, AuthenticatedController
in this case, to provide a method with current_user
. I used this blog post for inspiration.
It all seems to work just fine, but I am using RubyMine to develop, and it complains about using a variable instead of a constant in the class definition. It raises the question of whether this is a good idea or not.
So, is this approach okay? Are there some gotchas that I am not seeing? And are there any alternatives to this method?
Upvotes: 1
Views: 144
Reputation: 20408
As Andrew points out this is fine in Ruby, and the warning is a problem with RubyMine. One possible approach to work-around the warning and still get the same ruby semantics is to use Class::new
instead of the class
keyword to define your class:
MyEngine::ApplicationController = Class.new(MyEngine.authenticated_controller) do
#some code
end
Upvotes: 0
Reputation: 96934
This is completely okay—so long as the variable contains a Class instance when this code runs (which would give a TypeError: “superclass must be a Class”).
Ruby only gives this error when you have a non-constant named class/module, e.g.:
class c; end
module m; end
as opposed to
class C; end
module M; end
So either you have this issue elsewhere (unlikely if everything is working as this is an error, not a warning), or RubyMine is incorrectly giving you the error for some reason. Ruby gives no warnings for what you have.
Upvotes: 1