Ruby on rails Rails,创建一个没有视图的方法是一个好的实践吗?

Ruby on rails Rails,创建一个没有视图的方法是一个好的实践吗?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我的视图中有一个模型AdminUser,一个文件夹admin\u users,只有两个视图(仪表板和索引),还有一个AdminUsersController,它是: class AdminUsersController < ApplicationController def dashboard end def index end def login if params[:admin_user][:username].present? && p

我的视图中有一个模型
AdminUser
,一个文件夹
admin\u users
,只有两个视图(仪表板和索引),还有一个
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
class AdminUsersControllerparams[:admin\u user][:username])。首先
如果找到用户
authorized_user=found_user.authenticate(参数[:admin_user][:password])
会话[:admin]=参数[:admin\u user][:用户名]
结束
结束
如果是授权用户
重定向到:controller=>“admin\u users”,:action=>“dashboard”
其他的
呈现:nothing=>true,:status=>:ok
结束
结束
结束
虽然我有一个登录操作,但我没有它的视图,因为我并不真正需要它

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


我应该用另一种方式吗?

没有视图完全可以。当您向控制器添加不需要视图的方法(例如创建/更新/销毁方法)时,您会注意到需要在该方法中添加一个指向另一个视图的“render”或“redirect_to”语句。这告诉rails不要遵循规范,而要查找具有该操作名称的视图。

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

  • 返回前重定向的操作,例如标准Rails创建和更新操作
  • 内联呈现的操作,例如CSV生成器
  • 呈现ajax结果的操作
  • 作为REST API端点的操作
公约适用于最常见的情况,但也有适用于不太常见但仍然有效的情况的公约

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

如果您碰巧有一个操作(如问题中的示例所示),您可以通过提前返回来说服Rails绕过对与该操作对应的视图的搜索。虽然看起来将u重定向到就足够了,但实际上这只是响应的一部分。实现这一点的常用方法是使用
重定向到:页面并返回
习惯用法

对于给定的示例,请使用以下命令:

if authorized_user
  redirect_to :controller => 'admin_users', :action => 'dashboard' and return
else
  render :nothing => true, :status => :ok
end 
有关更多详细信息,请参阅这些优秀的问题和答案:


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

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

auth系统的常见设置是为会话设置一个特定的控制器——这是系统中非常重要的一部分,因此它有自己的控制器

一个好的做法是尽量坚持标准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

没错。如果你不需要查看,那么你可以跳过它。就像我们不需要销毁和创建视图一样,通常最好遵循映射到
resources
routes.rb
文件中生成的REST端点的标准名称。这里有一点混乱,
DashboardController
中的
index
show
会使
DashboardController
更好。拥有几个人烟稀少的控制器通常比一个塞满垃圾的控制器要好。也不要忘了
AdminUser。通过(用户名:…)
查找比
where(…)好。首先
@tadman非常感谢您的建议。“拥有几个人烟稀少的控制器通常比一个塞满垃圾的控制器要好。”你建议我应该为管理员用户使用多个控制器吗?这对我来说似乎有点奇怪,我以为每个模型都有一个控制器?一开始看起来会很奇怪,特别是如果一些模型只有一个动作,但从长远来看,它会让事情井然有序。您还需要为所有要继承的管理操作创建一个基本控制器,该控制器在允许某人执行任何操作之前检查其角色是否正确。@tadman例如,我是否应该仅对具有视图的方法使用“admin\u users\u controller”并创建“admin\u users\u login\u controller”仅用于登录功能?这是一个很好的列表!值得一提的是,如果你有一个方法不是一个动作,它不会呈现,你应该把它放在
protected
部分来保持它的条理性。@tadman很好的建议。我添加了关于非公共方法的注释。这无疑为答案增添了一些有用的东西。干杯