用于操作(更新、删除等)和错误检查的 Rails 模式
Posted
技术标签:
【中文标题】用于操作(更新、删除等)和错误检查的 Rails 模式【英文标题】:Rails pattern for action(update, delete, etc) & error checking 【发布时间】:2014-05-04 17:35:42 【问题描述】:我是 Rails 的新手,所以我想知道下面是否存在已知模式(我的 Google 技能在这里失败了)。
我所有的 Rest 控制器都遵循以下基本模式:
检查项目是否存在 --> 如果存在则获取项目 --> 如果不存在则返回错误 --> 如果存在则执行某些操作 --> 检查操作是否失败 --> 如果失败则返回错误--> 如果没有,则成功。所以两个动作,两个错误检查。我的问题是:这是一个很好的正确模式,还是我应该做一些不同的事情?
“销毁”方法示例:
def destroy
if @team = fetch_team
if @team.destroy
render json: message: "team: '#params[:id]' deleted", status: 200
else
render json: message: "error: #@team.errors.full_messages", status: 500
end
else
render json: message: "team: '#params[:id]' not found", status: 404
end
end
##
def fetch_team
Team.find_by(name: params[:id])
end
【问题讨论】:
【参考方案1】:我会从单个操作中重构您的一些逻辑,使其更干燥。
首先,我会将fetch_team
的检查移到before_action
过滤器中。这样一来,您就可以让 Rails 为多个操作运行它,例如 show
、update
和 destroy
。
当你调用Team.find_by!
(注意爆炸)时,如果没有找到记录,Rails 将抛出一个ActiveRecord::RecordNotFound
异常。因此,如果没有找到记录,您可以使用rescue_from
执行您需要执行的操作。这样一来,您就无需在多个操作中重复该逻辑。
class TeamsController < ApplicationController
before_action :find_team, only: [:show, :update, :destroy]
rescue_from ActiveRecord::RecordNotFound, with: :not_found # This can be moved to `ApplicationController` if you follow this pattern in ALL of your controllers
def destroy
if @team.destroy
render json: message: "team: '#params[:id]' deleted" , status: 200
else
render json: message: "error: #@team.errors.full_messages" , status: 500
end
end
private
def find_team
@team = Team.find_by!(name: params[:id])
end
def not_found
render json: message: "team: '#params[:id]' not found" , status: 404
end
end
说了这么多,我觉得not_found
中的定义是非常大方的。通常,当find_by!
失败时,我会让控制器抛出它自己的 404 异常,并期望客户端能够识别 404 标头并做出相应的响应。如果您希望显示示例中的错误消息,这取决于您。
【讨论】:
这看起来好多了,谢谢。但是似乎我需要ActiveRecord::RecordNotFound
而不是ActiveRecord::NotFound
编辑了我的答案。你有证据证明我在浏览器中编码了整个答案。至少我是一致的。 :)【参考方案2】:
让我们使用销毁操作示例:
我见过的常见方法是让控制器销毁动作像这样简单:
def destroy
@team = Team.find(params[:id]) # first find the object you want to delete
@team.destroy # if it's found, call the destroy method on it. if it's not found, you won't get to this line. it'll raise error.
respond_to do |format|
format.html redirect_to teams_url #this is redirecting to your chosen path once it's destroyed.
format.json head :no_content
end
end
但在您看来,您将在继续删除之前为用户提供改变主意的机会:
app/views/teams/show.html.erb
<%= link_to 'Delete team', @team class: 'btn btn-primary', method: :delete, data: confirm: 'Are you sure you want to delete this team?' %>
这将提示弹出消息。他们可以点击cancel
或点击ok
继续删除
【讨论】:
以上是关于用于操作(更新、删除等)和错误检查的 Rails 模式的主要内容,如果未能解决你的问题,请参考以下文章
Rails ajax 调用同时产生 404 和 500 错误
Ajax 和 Rails 4:创建实例变量并更新视图而不刷新