我有一个模型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的方式做某事。
我应该用另一种方式吗?
答案 0 :(得分:7)
您无需拥有视图。事实上,存在一些不需要视图的好理由:
这些惯例适用于最常见的情况,但也有一些常见的,但仍然有效的情况。
请注意,不应将可渲染操作的方法放在类的protected
或private
部分中,以使它们与实际操作分开。不要在控制器的公共接口中公开任何方法,除了那些旨在进行操作的方法。
如果您确实遇到了某个操作(如问题中的示例所示),您可以通过提前返回来说服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