我对Rails很新,并且有一个我无法理解的问题 关于建筑上“正确”的做法,我要四处寻找。
问题涉及我所谓的子控制器。情景是 这样:
我有一系列页面,其中包含某个表单的面板 一些信息(想想gitHub右上角的用户面板)。
因此,在我的应用程序中,我有控制器为页面生成数据 并提出答案,这是好的,但当涉及到这一点 面板,在我看来,你会想要某种控制器动作 致力于生成此面板及其视图。
问题是,你是怎么做的?如何渲染'sub 控制器'来自视图?
答案 0 :(得分:3)
我会将逻辑放在帮助器或模块中。 (http://api.rubyonrails.org/classes/ActionController/Helpers/ClassMethods.html)
然后渲染您想要显示这些内容的部分。 (http://api.rubyonrails.org/classes/ActionView/Partials.html)
答案 1 :(得分:2)
就像赫尔曼所说,如果你需要在控制器切换到视图后生成逻辑(即,页面控制器生成页面视图,但你想要一个自定义面板),那么就把它放在帮助器中。或者,在切换到视图之前,在Pages控制器中调用单独的方法。或者,如果它有很多逻辑,请创建一个模块并将其粘贴到/ lib文件夹中。因此,你可以拥有一个完整的Panel模块,其中的方法可以生成Panel的不同部分,并由控制器调用。但是如果你想从视图中调用这些方法,那么你应该使用一个帮助器。
答案 2 :(得分:2)
我不认为模块是这里所需要的,模块是跨类的一小部分共享行为所必需的。
我认为这里需要了解ApplicationController的继承以及布局
所以,例如,我的布局可能如下所示:
<html>
<head><title>Foo</title></head>
<body>
<%= render :partial => (current_user ? "/shared/user_widget_bar" : "/shared/login_bar") %>
<%= yield %>
</body>
</html>
我想用它的任何代码都会放在我的ApplicationController中,因为它会在我的大部分应用程序中共享:
before_filter :generate_user_widget
def generate_user_widget
if current_user
@avatar = ...
@unread_messages = ...
end
end
我明白它属于一个单独的控制器可能更干净但老实说,除非代码很大,它没关系,甚至可以放在一个模块中,然后由ActionController包含。但是,如果考虑它的范围,它确实需要在ApplicationController中。
如果有更多相关页面,例如,你有一个管理多个站点的Rails应用程序,并且你想要在特定站点上共享行为,请尝试创建一个没有操作且只有私有方法的父控制器,任何控制器需要访问这些方法才能继承它。这样你就可以在过滤器之前应用到继承它的所有控制器,省去了忘记在非父控制器中添加一个控制器的痛苦。
e.g:
class SiteA::SiteAParentController < ApplicationController
before_filter :generate_user_widget
...
end
class SiteA::ProductController < SiteA::SiteAParentController
def index
...
end
end
答案 3 :(得分:1)
好吧,如果您确实需要从视图中调用控制器操作,则可以使用组件。它们是框架的一部分,现在它们只作为插件存在。一个似乎维护良好的插件就在这里:http://github.com/cainlevy/components/tree/master
来自其文档:
==用法
请注意,这些示例非常简单,使用Rails partials可以更好地实现。
===发电机
运行script/generator users details
将创建一个带有“详细信息”视图的UsersComponent。然后你可能会充实
像这样的模板:
class UsersComponent < Components::Base
def details(user_or_id)
@user = user_or_id.is_a?(User) ? user_or_id : User.find(user_or_id)
render
end
end
===来自ActionController
class UsersController < ApplicationController
def show
return :text => component("users/detail", params[:id])
end
end
===来自ActionView
<%= component "users/detail", @user %>