【问题标题】:Rails, is it a good practice to create a method without a view?Rails,创建没有视图的方法是一种好习惯吗?
【发布时间】:2016-09-09 12:44:00
【问题描述】:

我的视图中有一个模型AdminUser,一个文件夹admin_users,只有2 个视图dashboardindex),和一个AdminUsersController,即:

class AdminUsersController < ApplicationController
  def dashboard
  end

  def index
  end

  def login
    if params[:admin_user][:username].present? && params[:admin_user][:password].present?
      found_user = AdminUser.where(:username => params[:admin_user][:username]).first
      if found_user
        authorized_user = found_user.authenticate(params[:admin_user][:password])
        session[:admin]=params[:admin_user][:username]
      end
    end
    if authorized_user
       redirect_to :controller => 'admin_users', :action => 'dashboard'
    else
      render :nothing => true, :status => :ok
    end 
  end
end

虽然我有一个登录操作,但我没有它的视图,因为我真的不需要它。

但是 Rails 搜索视图的事实让我觉得我做错了什么;或者至少不以 Rails 的方式做某事。

我应该以其他方式执行此操作吗?

【问题讨论】:

  • 没错。如果您不需要查看,则可以跳过它。就像我们不需要销毁和创建视图
  • 通常最好遵守映射到resourcesroutes.rb 文件中生成的REST 端点的标准名称。你这里的东西有点乱,dashboardDashboardController 中最好是indexshow。拥有几个人烟稀少的控制器通常比一个塞满垃圾的控制器要好。也别忘了AdminUser.find_by(username: ...)where(...).first 好。
  • @tadman 非常感谢您的建议。 “拥有几个人烟稀少的控制器通常比一个塞满垃圾的控制器要好。”您是否建议我应该为 admin_users 使用多个控制器?这对我来说有点奇怪,我以为每个型号都有一个控制器?
  • 一开始会觉得很奇怪,特别是如果有些人只有一个动作,但从长远来看,它会让事情井井有条。您还需要为您的所有管理操作创建一个基本控制器以继承,该控制器在让他们做任何事情之前检查一个人是否具有正确的角色。
  • @tadman 例如,我是否应该只对带有视图的方法使用“admin_users_controller”,而只为登录功能创建一个“admin_users_login_controller”?

标签: ruby-on-rails ruby


【解决方案1】:

没有视野完全没问题。当您将不需要视图的方法添加到控制器时,例如创建/更新/销毁方法,您会注意到您需要在该方法中添加指向另一个视图的“render”或“redirect_to”语句.这告诉 Rails 不要遵循规范并寻找具有该动作名称的视图。

【讨论】:

    【解决方案2】:

    您不需要有视图。事实上,有很多很好的理由不需要视图:

    • 在返回之前重定向的操作,例如标准 Rails 创建和更新操作
    • 内联呈现的操作,例如 CSV 生成器
    • 呈现 ajax 结果的操作
    • 作为 REST API 端点的操作

    约定适用于最常见的情况,但也有适用于不太常见但仍然有效的情况的约定。

    请注意,不打算成为可渲染操作的方法应放在类的protectedprivate 部分,以使它们与实际操作分开。不要在控制器的公共接口中公开任何方法,除了那些打算作为操作的方法。

    如果你碰巧有一个动作(就像问题中的例子一样),你可以通过提前返回来说服 Rails 绕过对对应于该动作的视图的搜索。虽然看起来redirect_to 就足够了,但它实际上只是响应的一部分。执行此操作的常用方法是使用 redirect_to :page and return 成语。

    对于给出的例子,使用这个:

    if authorized_user
      redirect_to :controller => 'admin_users', :action => 'dashboard' and return
    else
      render :nothing => true, :status => :ok
    end 
    

    有关详细信息,请参阅这些优秀的问题和答案:

    【讨论】:

    • 这是一个不错的清单!值得一提的是,如果你有一个不是动作的方法,它不会渲染,你应该把它放在protected 部分以保持它的组织。
    • @tadman 很好的建议。我添加了关于非公共方法的注释。它肯定会为答案增加一些有用的东西。干杯!
    【解决方案3】:

    在很多情况下,控制器操作不需要相应的视图,Michael Gaskill 对此进行了很好的介绍。

    您应该更担心的另一件事是单一职责原则 (SRP)。理想情况下,应用程序中的每个控制器都应对应于单个 RESTful 资源。例如,UsersController 应该只对 CRUD 用户负责。

    身份验证系统的常见设置是为会话设置一个特定的控制器 - 它是系统中非常重要的一部分,因此值得拥有自己的控制器。

    一个好的做法是尽可能地坚持标准的 CRUD 操作(显示、索引、新建、创建、编辑、更新、销毁),我们在下面通过将会话视为资源来执行这些操作:

    # config/routes.rb
    resource :session
    
    # create a helper for the authentication logic
    # this avoids duplicating it all over your controllers!
    module SessionsHelper
      def current_user
        @current_user ||= User.find(session[:user_id]) if session[:user_id]
      end
    end
    
    # minimal example
    class SessionsController
    
      include SessionsHelper
    
      # the login screen shown to users
      def new
      end
    
      # sign in a user
      def create
        @user = User.find_by(email: params[:email])
                    .try(:authenticate, params[:password])
        if @user
          reset_session
          session[:user_id] = @user.id
          @current_user = @user
          redirect_to root_path, success: 'You have been signed in.'
        else
          render :new, error: 'Incorrect email or password.'
        end
      end
    
      # sign out user
      def destroy
        if current_user
          reset_session
          redirect_to root_path, notice: 'You have been signed out.'
        else
          redirect_to root_path, error: 'You are not signed in'
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2012-02-21
      • 2012-03-01
      • 1970-01-01
      • 2014-07-21
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 2013-12-31
      • 2020-12-14
      相关资源
      最近更新 更多