如果您的菜单中有一个布局,可以从数据库中获取其菜单项。 Rails应用程序中建议放置该调用并将其分配给布局使用的实例变量的位置在哪里?
1. @menuitems # exists in application.html.erb
2. @menuitems = MenuItem.find(:all) # code exists somewhere (where should this exist?)
@womble - 是的,before_filter会有所帮助,但我必须将它包含在使用此布局的所有控制器中,或者这是我可以放在application_controller.rb中的内容,子控制器和附带的视图是否能够看到那个实例变量?
答案 0 :(得分:8)
是的,您可以在应用程序控制器中定义并将其设置为before_filter
。所有控制器都会在过滤之前调用它。以这种方式设置全局实例变量并不罕见。
另一种方法是在应用程序控制器中使用memoization方法,并将set作为辅助方法,与流行的current_user
方法类似。然后,实例变量将由memoization函数很好地包装。例如:
def menu_items
@menu_items ||= MenuItem.all
end
helper_method :menu_items
现在只需从您的布局中调用menu_items
,而不是直接使用@menu_items
。
我认为值得一提的是将它放在应用程序控制器中是不必要的。如果您只想在视图/布局中使用它,可以将它直接放在辅助模块中,例如LayoutHelper。您需要在应用程序控制器中使用helper :all
(或至少helper :layout
)。
这有点个人偏好 - 您可能会或可能不喜欢在助手中进行ActiveRecord呼叫。但是,如果有时间这样做,那就是它。
答案 1 :(得分:0)
Martin Fowler描述了在模板代码中直接调用活动记录函数是Rails MVC结构的一个弱点。对于最佳实践,您应该在模型类中创建成员函数,并从模板中调用该函数(包括布局模板)。
答案 2 :(得分:0)
这种调用应该存在于系统的Controller层中。既然看起来它需要在全球范围内发生,我可能会把它放在before_filter
中,并且讨厌自己做这件事。无论你采用哪种方式,获取布局所需的数据在Rails中都会有点麻烦。