我正在编写一个可配置的Rails引擎。我有一个authentication_helper
配置选项来定义在需要身份验证的所有控制器中before_action
中应该调用哪个帮助程序。
问题是我无法从引擎的控制器访问父应用程序的帮助程序。 My understanding发生这种情况是因为引擎已被隔离。
我考虑使用块而不是方法名称,但我不确定这是否可行,或者我是否能够从控制器外部干净地访问授权逻辑。
我过去使用过的Active Admin有一个类似的配置选项。我注意到他们的发动机没有隔离,所以也许我高估了引擎隔离的重要性?
是否有一种优雅的方式可以获得引擎隔离的好处,同时还允许这种自定义?或者我应该完全放弃隔离?
编辑#1
Brad Werth指出我正确的方向,因为这适用于继承自ApplicationController::Base
的常规控制器:
module MyBigFancyEngine
class Engine < Rails::Engine
isolate_namespace MyBigFancyEngine
config.to_prepare do
# Make the implementing application's helpers available to the engine.
# This is required for the overriding of engine views and helpers to work correctly.
MyBigFancyEngine::ApplicationController.helper Rails.application.helpers
end
end
end
但是,我的引擎ApplicationController
继承自RocketPant::Base
,但未提供helper
方法。我试过使用一个简单的include
(适用于常规控制器),但这也不起作用(控制器找不到帮助器)。
有什么想法吗?
答案 0 :(得分:5)
您可以通过在engine.rb文件中包含以下代码来公开可用于引擎的实现应用程序帮助程序:
<强> engine.rb 强>
module MyBigFancyEngine
class Engine < Rails::Engine
isolate_namespace MyBigFancyEngine
config.to_prepare do
# Make the implementing application's helpers available to the engine.
# This is required for the overriding of engine views and helpers to work correctly.
MyBigFancyEngine::ApplicationController.helper Rails.application.helpers
end
end
end
答案 1 :(得分:2)
RailsAdmin引擎也是独立的,但它们具有您想要实现的相同配置选项。它们具有可配置的before_filters,用于身份验证和授权。看看this。
据我所知,他们只是将父控制器子类化为::ApplicationController
,或者你可以配置一个(ref)。
对于您的控制器,您可以创建自己的EngineController
,它继承自RocketPant::Base
,并且可能只是创建一个方法,直接通过父控制器上的send
调用配置的身份验证方法。
由于RocketPant::Base
类不从ApplicationController::Base
继承,我猜你必须找到一些自定义的方法,并且不能采用Rails引擎的常规方法。也许你也可以尝试向rocket_pant repo提交一个问题,添加helper
方法。据我所知,他们很快就想在2.0(ref)中继承ApplicationController::Base
。
答案 2 :(得分:0)
我认为你保持隔离是好的冲动 - 因为一种解决方案依赖于一种方法而只是在那里&#39;如果s.th.是一个痛苦的调试。使用您的宝石在应用程序中出错(即方法名称中的拼写错误)。
此外,如果你的宝石进化,有一天它不会需要这种方法,以明确的方式非常方便地给出一个可怕的错误:
您可以提供在初始化程序中调用的配置方法:
YourGem.configure do |config|
config.add_callback { MyApp.doIt() }
end
答案 3 :(得分:0)
我发现了discussion particularly insightful。隔离引擎助手下的Rails Engine API中也有一些有趣的想法。
Rails Engine API文档帮助我找到了url_helpers的一个很好的解决方案
答案 4 :(得分:0)
您现在可能已经搬走了,但是如果其他人需要访问“父应用程序”应用程序助手。您始终可以将其明确包含在引擎的应用程序控制器中。像这样:
include Rails.application.helpers