Rails子控制器?

时间:2009-04-01 09:06:43

标签: ruby-on-rails

我对Rails很新,并且有一个我无法理解的问题 关于建筑上“正确”的做法,我要四处寻找。

问题涉及我所谓的子控制器。情景是 这样:

我有一系列页面,其中包含某个表单的面板 一些信息(想想gitHub右上角的用户面板)。

因此,在我的应用程序中,我有控制器为页面生成数据 并提出答案,这是好的,但当涉及到这一点 面板,在我看来,你会想要某种控制器动作 致力于生成此面板及其视图。

问题是,你是怎么做的?如何渲染'sub 控制器'来自视图?

4 个答案:

答案 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 %>