我正在开发一个分类广告网站,几乎每个页面都会显示相同的侧边栏。从数据库中提取的类别列表。
我发现自己在每个控制器中复制相同的代码来执行此操作。即。
before_filter :load_categories
其中:load_categories执行简单的
private
def load_categories
@categories = Category.all
end
当你有很多控制器时,不是很干。
我有办法干这个过程吗?
答案 0 :(得分:3)
你可以将它放在ApplicationController上,但老实说我建议不要这样做。随着时间的推移,ApplicationController往往会成为一个大膨胀的blob,积累实际上没有相关的实用功能,绝对不是SRP。它可能变得丑陋。
我为保持DRY而做的是创建一个相关控制器可以继承的父控制器。把你的before_filter放在那里,让相关的类别使用控制器继承它。
也许:
class MainPagesController < ApplicationController
before_filter :load_categories
private
def load_categories
@categories = Category.all
end
end
class SomeController < MainPagesController
# etc.
end
如果您的应用程序很小,随着时间的推移不会显着增长,并且您真正在几乎所有页面上加载@categories,那么将它放在ApplicationController上可能会有意义。但我倾向于过度干扰我的代码。非常小的具有孤立功能的类从来都不是坏事。
答案 1 :(得分:0)
您可以将def load_categories
定义放在ApplicationController
中,并且可以从您应用中的每个控制器访问它。
如果您希望为每个控制器执行before_filter :load_categories
,也可以将ApplicationController
放入Category.all
。
虽然坦率地说,对我来说这似乎不是一个巨大的代码冗余案例。实际上,只需在您需要类别的每个操作/视图中调用{{1}}都可能更简单。由于结果是缓存的,因此没有性能损失。
答案 2 :(得分:0)
您可以将您的方法放在ApplicationController和before_filter中。
如果你想在一个特定的控制器中避免它,你可以在
后跳过它