Rails,创建一个没有视图的方法是一个好习惯吗?

时间:2016-05-13 10:44:05

标签: ruby-on-rails ruby

我有一个模型AdminUser,我的视图中的文件夹admin_users只有 2个视图信息中心索引)和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-y的方式做某事。

我应该用另一种方式吗?

3 个答案:

答案 0 :(得分:7)

您无需拥有视图。事实上,存在一些不需要视图的好理由:

  • 在返回之前重定向的操作,例如标准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 

有关详细信息,请参阅以下优秀问题和答案:

答案 1 :(得分:4)

没有视图是完全没问题的。当您向控制器添加不想要视图的方法时,例如create / update / destroy方法,您会发现需要添加&#34;渲染&#34;或&#34; redirect_to&#34;该方法中指向另一个视图的语句。这告诉rails不要遵循规范并查找具有该动作名称的视图。

答案 2 :(得分:2)

在许多情况下,控制器操作不需要Michael Gaskill所涵盖的相应视图。

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

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