从包含在父类中的模块调用父类的子类的私有方法是否可以,特别是当它涉及Rails中的ApplicationController,Controllers和lib模块时?
考虑是否需要更改控制器名称方法名称以反映模型名称(到文章)更改。
我觉得编码非常糟糕,想知道社区对此的看法
Rails应用程序的示例:
/lib/some_module.rb
module SomeModule
include SomeModuleResource
def filtering_method
calling_method
end
def calling_method
fetch_object
end
end
/lib/some_module_resource.rb
module SomeModuleResource
def fetch_object
note
end
end
/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include SomeModule
before_action :filtering_method
end
/app/controllers/notes_controller.rb
class NotesController < ApplicationController
def show
end
private
def note
@note ||= Note.find(param[:id]))
end
end
答案 0 :(得分:1)
我认为这不是必要的,虽然当你期望包含该模块的类中的某个接口(方法,变量等)时,我会添加以下内容:
module SomeModuleResource
def fetch_object
note
end
private
def note
raise NotImplementedError
end
end
这样,当#note
被调用而没有实现它时(因为你忘了它是必需的或其他什么),会引发NotImplementedError
。
另一种选择是解决它并创建更通用的解决方案。例如,如果所有控制器的行为与上述相同,则可以执行以下操作:
module SomeModuleResource
def fetch_object
note
end
private
def note
klass = params[:controller].classify.constantize
instance = klass.find(params[:id])
var_name = "@#{klass.underscore}"
instance_variable_set(var_name, instance) unless instance_variable_get(var_name)
end
end
您还可以创建一个类助手方法,如before_action
,以便您可以传递自己的实现。
module SomeModule
include SomeModuleResource
def self.included(base)
base.extend(ClassMethods)
end
def filtering_method
calling_method
end
def calling_method
fetch_object
end
module ClassMethods
def custom_before_action(&block)
define_method(:note, &block)
private :note
before_action :filtering_method
end
end
end
现在,您可以在每个控制器中使用custom_before_filter { @note ||= Note.find(params[:id]) }
(包括之后)。
以上只是为了向您提供想法。我确信你能找到更好的问题解决方案,但这有望为你指明正确的方向。
请参阅:Alternatives to abstract classes in Ruby?。或者在Ruby中搜索抽象类,你会在这个主题上找到更多。