重构这个控制器?
class ArticlesController < ApplicationController
def index
@articles = Article.by_popularity
if params[:category] == 'popular'
@articles = @articles.by_popularity
end
if params[:category] == 'recent'
@articles = @articles.by_recent
end
if params[:category] == 'local'
index_by_local and return
end
if params[:genre]
index_by_genre and return
end
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @articles }
end
end
def index_by_local
# 10 lines of code here
render :template => 'articles/index_by_local'
end
def index_by_genre
# ANOTHER 10 lines of code here
render :template => 'articles/index_by_genre'
end
end
正如你从上面看到的。我的控制器并不完全薄。它的作用是,根据传递的参数,它与模型交互以过滤掉记录。
如果传递了 params[:local]
或 params[:genre]
。然后它分别调用自己的方法(def index_by_local
和def index_by_genre
)进行进一步处理。这些方法还加载自己的模板,而不是 index.html.erb
。
这对于控制器来说是非常典型的吗?或者我应该以某种方式重构它?
class ArticlesController < ApplicationController
def index
@articles = Article.by_popularity
if params[:category] == 'popular'
@articles = @articles.by_popularity
end
if params[:category] == 'recent'
@articles = @articles.by_recent
end
if params[:category] == 'local'
index_by_local and return
end
if params[:genre]
index_by_genre and return
end
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @articles }
end
end
def index_by_local
# 10 lines of code here
render :template => 'articles/index_by_local'
end
def index_by_genre
# ANOTHER 10 lines of code here
render :template => 'articles/index_by_genre'
end
end
As you can see from above. My controller is not exactly thin. What its doing is, depending on the params that were passed, it interacts with the model to filter out records.
And if params[:local]
or params[:genre]
was passed. Then it calls its own methods respectively (def index_by_local
and def index_by_genre
) to do further processing. These methods also load their own template, instead of index.html.erb
.
Is this quite typical for a controller to look? Or should I be refactoring this somehow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我们可以将前几行移到模型(article.rb)中:
这样我们就可以使用单元测试来完整地测试文章获取逻辑。
一般来说,将与获取模型内的记录相关的所有代码移至模型中。
一般来说,控制器
[这些通常必须是功能
调用模型]
We can move the first few lines into the model(article.rb):
In this way we can completely test the article fetching logic using unit tests.
In general move all the code related to fetching records inside model.
Controllers in general
[These must typically be function
calls to model]
我将为您想要使用的每个集合定义范围。
然后在你的控制器操作中,像这样:
I would define scopes for each of the collections you want to use.
Then in your controller action, something like this: