我有一个足够大的控制器类,这是一个不好的做法(Rubocop抛出这个警告:类定义太长)。
该类有许多私有方法,它们都计算重定向到的路径,因此它是一个控制器问题。
怎么可能被重构?
示例代码:
class PostController
def new
@post = Post.new
end
def create
@post = Post.new(post_params)
# ...
end
# more resources methods
private
def post_params
# ...
end
def post_url(post)
if params['submit-save'] || params['submit-publish']
url_for [:edit, post]
else
url_for [:review, post]
end
end
def next_post_url(post)
next_post = post.find_next
if next_post
url_for [:edit, post]
else
some_path(next_post)
end
end
# some more methods
end
答案 0 :(得分:0)
从你对问题的讨论中,我的想法是确定计算重定向路径的各种私有方法是否属于一个特殊目的类,它抽象了路径计算逻辑的各个方面,或者可能只是一个模块,控制器混入。正确的答案将在很大程度上取决于您在各种私有方法中的逻辑。一个简单的模块不太可能是正确的方法,因为您只是将代码移动到其他地方以满足任意度量标准。确定所有私有方法的原因并提出更好的抽象可能是正确的方法,但可能会有不同的模式发挥作用。
本文中讨论的许多相同模式将适用于超重控制器和模型:7 Patterns to Refactor Fat ActiveRecord Models
答案 1 :(得分:0)
因此,从评论中得出结论,我喜欢这两个想法:
答案 2 :(得分:0)
我同意最后一句话总是来自开发人员,但是如果你添加像rubocop这样的工具是为了鼓励你编写一个更好的代码,那么添加rubocop然后禁用一些检查是没有意义的。
我也不会使用帮助方法,背后的原因是一个类应该只有一个责任,所以它应该只有一个行为。人们倾向于将所有类型的方法放在帮助者中,具有完全不同行为的方法赋予该类许多不同的职责。如果它的所有方法只有一个且只有一个目的,我会使用帮助器
在您的特定情况下,我会更倾向于将知识提取到普通类中。尝试识别不同的行为并将其封装到类中
在这种情况下,看起来你有一些网址构建器,所以一个可行的解决方案可能是这样的:
class PostController
def new
@post = Post.new
end
def create
@post = Post.new(url_builder.post_url)
# ...
end
# more resources methods
private
def url_builder
UrlBuilder.new(self, params)
end
end
class UrlBuilder
def initialize(self, params)
@self = self
@params = params
end
def post_url(post)
if params['submit-save'] || params['submit-publish']
self.url_for [:edit, post]
else
self.url_for [:review, post]
end
end
def next_post_url(post)
next_post = post.find_next
if next_post
self.url_for [:edit, post]
else
some_path(next_post)
end
end
private
attr_reader :self, :params
end
这不是一个完全可行的例子,因为我不知道你的控制器的整个实现,只是一个需要一些调整的可行解决方案。关于该解决方案的几点要说的是: