【问题标题】:Which controller should I put @notifications in?我应该将@notifications 放入哪个控制器?
【发布时间】:2015-06-23 23:50:00
【问题描述】:

想象一个典型的现代网络应用程序 - 在导航栏或顶部的一些导航元素中,有一个 notifications 菜单,它告诉用户自上次访问以来他们收到了多少通知。

它也可能有一个下拉菜单,他们可以清除现有通知或仅查看它们。

鉴于这些通知需要出现在所有视图中,我应该将其逻辑放在哪里?在我的ApplicationController?出于某种原因,这感觉不对 - 但我看不到任何其他解释。

另外,我应该把实际的部分放在通用/shared/ 文件夹中吗?

对于那些具有Dashboard 控制器(即非静态资源)的应用程序,它只是充当大量此类信息的中心枢纽,解决此问题的最佳方法是什么?在将包含在Dashboard 中的部分结构方面。

编辑 1

根据下面 Kevin 和 Collin 给出的答案,我需要更进一步。

他们推荐 Facade 模式,正如 Sandi Metz 通过Thoughtbot here 解释的那样。

但是,这是我的问题。在我的 application.html.erb 中,我有一个部分正在渲染 - <%= render partial: "shared/navbar" %>. 在那个部分中,我希望能够调用某些东西(例如 @notifications)。我将如何访问该实例变量和其他共享变量/资源上将在此 facades/dashboard.rb 中声明的其他部分?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4


    【解决方案1】:

    使用Facade pattern,如this article 中所述。

    请参阅以下部分:仅在控制器中实例化一个对象

    他们甚至在他们的示例中使用仪表板上的通知。 :)

    【讨论】:

    • 我真的很喜欢你前进的方向。你对科林的回答碰巧有我的 cmets 的回答吗?
    【解决方案2】:

    在这里记住几件事很重要:

    首先,如果这是唯一可能去的地方,请仅将此逻辑放入您的ApplicationController。由于这个通知菜单很可能在整个应用程序中持续存在,这可能就是它所属的地方。

    其次,你可以实现这个 Facade,同时仍然保持你的 DashboardsController 相当 RESTful。控制器应该只负责实例化一个对象,对吧?因此,这样做是有意义的:

    app/controllers/dashboards_controller.rb
    
    class DashboardsController < ApplicationController
      def show
        @dashboard = Dashboard.new(current_user)
      end
    end
    
    
    app/facades/dashboard.rb
    
    class Dashboard
      def initialize(user)
        @user = user
      end
    
      def new_status
        @new_status ||= Status.new
      end
    
      def statuses
        Status.for(user)
      end
    
      def notifications
        @notifications ||= user.notifications
      end
    
      private
    
      attr_reader :user
    end
    
    
    app/views/dashboards/show.html.erb
    
    <%= render 'profile' %>
    <%= render 'groups', groups: @dashboard.group %>
    
    <%= render 'statuses/form', status: @dashboard.new_status %>
    <%= render 'statuses', statuses: @dashboard.statuses %>
    

    仪表板模型为您提供所需的所有相关信息,并且您的控制器可以专注于单个实体。美丽的!

    更新

    为了在任何局部变量中使用您的 @dashboard 实例变量,建议您使用局部变量来渲染它,它本质上是在局部变量内部使用的指定变量。

    Here's a great link 了解如何开始将局部变量传递给局部变量。

    【讨论】:

    • 我的/views/dashboard/index.html.erb 会是什么样子?我喜欢你的方向,但我如何/为什么要使用 @dashboard 对象?我也没有Dashboard 模型,它实际上只是一个控制器和一组视图,用于显示来自应用程序内所有其他资源的信息。
    • 或者更恰当地说,这就是问题所在。在我的application.html.erb 中,我渲染了一个部分 - &lt;%= render partial: "shared/navbar" %&gt;。在那个部分,我希望能够调用某些东西(例如 @notifications)。我将如何访问该实例变量和其他 shared variables/resources 将在此 facades/dashboard.rb 中声明的其他部分?
    • 对。您可以创建一个完全不需要数据库支持的 PORO(普通旧 Ruby 对象)的仪表板模型。这是一个最佳实践,因为您不应该关心 Rails 控制器中的业务逻辑,它们最终应该只实例化一个实体。我已经更新了我的答案,以展示像 views/dashbard/show.html.erb 这样的东西的外观,以及如何在部分中使用它。
    • 我了解 Collin,我正在努力解决的问题是如何将其从 dashboard 外观中抽象出来(即在从应用程序布局调用的一般共享部分中,而不是在仪表板视图)。这就是我试图在我的 cmets 和更新的问题中得到的。您所做的只是从 Thoughtbot 文章中粘贴了更多代码,这并没有真正解决我的问题。如果我使用DashboardsController 作为我调用其中所有部分的基础,那将起作用。就我而言,我是通过我的application.html.erb 给他们打电话的。
    • 我粘贴了 Thoughtbot 文章中的更多代码,因为我认为它准确地解决了您的问题。无论如何,如果您希望它在所述控制器中包含的部分中持久存在,为什么不直接从您的Dashboard 调用一个新的Dashboard 模型?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2017-02-13
    • 2013-06-24
    • 2014-07-27
    • 2016-03-31
    相关资源
    最近更新 更多