应该如何有几个不同的控制器的行为设置公共实例变量使用的模板,但在操作运行后.
换句话说,我希望这在我的application_controller中工作.
class ApplicationController < ActionController::Base after_filter :set_something_common def set_something_common # All controllers' actions have queried the DB and set @foo for me... @bar = some_calculation_on(@foo) # ... and all templates expect @bar to bet set. end end
这不起作用,因为after_filter
渲染后运行.精细.但是正确的模式是什么?
同样,set_something_common
在操作之后运行是很重要的,因为这些操作会执行特定于案例的操作; 但他们都搞定了@foo
.
我的想法似乎都不理想:
呼吁set_something_common()
每一个需要它的行动的底部.
将所有控制器的特定于案例的代码重构为case_specific_code()
并强制它们按顺序运行:
before_filter :case_specific_code, :set_something_common
子类application_controller
并重新定义该index
方法.
有什么想法吗?谢谢.
几个控制者的索引()都进行分页,每个分页都采用参数@offset
和@limit
(通过全局before_filter
)来查看数据切片.大.现在我想要一个通用方法来为"下一个切片"链接计算RESTful URL.我被鼓励看到url_for()
生成一个返回相同资源的URL,所以我试过:
def set_something_common # really called set_next_url, truth be told @next_url = url_for(:offset => @offset + @limit, :limit => @limit) end
我会尝试猴子修补Fixnum,所以我可以@offset.next_url_for(self, @limit)
从模板中做一些事情,但我不确定它是否会起作用.想想看,如果我要修改模板,那么我也可以设置一个应用程序帮助器.我还不确定最好的解决方案是什么.
感谢大家的更新.我从中吸取了教训,就像全局变量一样,帮助者是有原因的,当它们明显有益且简洁时,不要被避开.
首先,您不希望尝试在控制器操作和模板渲染之间插入代码.为什么?因为您希望控制器操作可以自由选择要提供的响应类型.它可能只返回XML,JSON,头文件,重定向,什么都没有等等.这就是为什么在呈现响应后执行过滤器之后的原因.
其次,你不想要猴子补丁Fixnum
.我的意思是,也许你这样做,但我没有.至少不是这样,除非我能从中得到一些完全邪恶的语义好处,比如能够说出来3.blind_mice
.猴子修补它像这样的随机用例似乎是一个维护头痛的道路.
您提到将所有控制器的特定于案例的代码重构为前置过滤器并按顺序运行它们.这引起了我的注意...... @foo
在每种情况下都是一样的吗?如果是这种情况,那么在过滤器之前就可以正常工作:
before_filter :do_common_stuff def do_common_stuff @foo = common_foo @bar = do_something_with @foo end
这是一种完全合法的方法.但是如果@foo从控制器变为控制器......那么,你还有一些选择.
您可以将之前的过滤器分成两半,并为每个控制器自定义一个.
# application_controller: before_filter :get_foo, :do_something_common def do_something_common @bar = do_something_with @foo end # baz_controller: def get_foo @foo = pull_from_mouth end #baf_controller: def get_foo @foo = pull_from_ear end
但是你知道,如果这是一个简单的案例,不需要数据库访问或网络访问或类似的东西......你的情况不是......不要自杀.不要出汗.把它扔进帮手.这就是他们所要求的,帮助.你基本上只是将一些视图数据重新排列成一个稍微容易使用的形式.帮助是我的投票.而你可以命名它next_url
.:)