代码之家  ›  专栏  ›  技术社区  ›  cite

一个控制器,普通用户和管理员的不同视图

  •  6
  • cite  · 技术社区  · 15 年前

    在我的应用程序中,我有一个“用户”模型。每个用户可以有多个(电子邮件)地址,这些地址在模型“地址”中定义:

    Class User < ActiveRecord::Base
      has_many :addresses
    
    
      def is_authorized(op)
         # returns true or false
      end
    
      def is_owned_by(user)
         # returns true or false
      end
    end
    
    Class Address < ActiveRecord::Base
      belongs_to :user
    end
    

    在AddressController类中,当前登录的用户在“@user”实例变量中可用。控制器防止普通用户编辑、删除、查看不属于他们的地址,但允许管理用户编辑这些地址。AddressController类可以询问AddressModel当前登录的用户是否正在执行正常或超级用户操作。

    这一切都很好地工作,数据库更新是按预期进行的,但是,我真的希望有不同的HTML视图,这取决于操作模式。我只能想出两种方法来实现这一点:

    1. 使操作模式(普通/特权)在AddressController类中已知(使用实例变量,例如@privileged),并在视图中使用“if”语句。
    2. 在地址控制器中使用类似“after_filter”的东西来呈现不同的布局。

    如果可以在两种完全不同的布局中显示执行单个控制器的结果,取决于其操作模式,那么实现这一点的好方法是什么?

    提前谢谢 斯特凡

    5 回复  |  直到 15 年前
        1
  •  9
  •   Shadwell    15 年前

    可以指定要用于在操作本身中显示操作结果的视图。也可以指定要使用的布局。例如:

    def my_action
      if @user.is_authorised(...)
        render :action => 'admin_action', :layout => 'admin'
      else
        render :action => 'non_admin_action', :layout => 'non_admin'
      end
    end
    

    这将使 admin_action.html.erb non_admin_action.html.erb 根据返回值 is_authorised . 这个 :layout 选项是,er,可选的,并引用视图/布局中的布局。渲染调用还有各种其他选项,您可以在 documentation for render .

        2
  •  6
  •   Staelen    15 年前

    您可以通过以下方式指定特定控制器或应用程序控制器中整个应用程序的视图布局:

    class SomeController < ApplicationController
      layout :set_layout
    
      def set_layout
        @user.is_authorized(...) ? "privileged_layout" : "normal_layout"
      end
    
      ...
    end
    

    你可以试着在这里弄明白: http://guides.rubyonrails.org/layouts_and_rendering.html#using-render 2.2.12查找布局

    希望这有帮助=)

        3
  •  3
  •   Dave Ray    15 年前

    你可以直接打电话给 render 方法在控制器操作结束时手动执行:

    if @privileged
        render :action => 'show_privileged'
    else
        render :action => 'show'
    end
    

    这将使 app/views/myview/show_privileged.html.erb app/views/myview/show.html.erb . 或者,您可以使用 :template 选项为呈现方法提供显式模板文件。

        4
  •  2
  •   Andy Gaskell    15 年前

    如果这是你的应用程序中唯一的控制器,你在哪里,如果/否则到处都是可能是好的。如果你在任何地方都开始做这种逻辑,就会发现你一次做的太多了。

    你接受的答案(很好,很有效!)有一个不同的布局和不同的视图,对我来说,控制器做的太多了-我将把这个拆分成一个管理控制器。

        5
  •  0
  •   Ryan Bigg Andrés Bonilla    15 年前

    您应该将管理操作放在管理命名空间中,并将其限制在该命名空间中。创建一个名为 admin 在控制器目录中,并在其中添加一个应用程序controller.rb:

    class Admin::ApplicationController < ApplicationController
      before_filter :check_authorized
    
      private
        def check_authorized?
          if !logged_in? || !current_user.admin?
            flash[:notice] = "You've been very bad. Go away.
            redirect_to root_path
          end
        end
     end
    

    现在,您可以将控制器放入这个名称空间,并使它们继承自 Admin::ApplicationController 也是。