我是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
答案 0 :(得分:2)
我会从个别行动中重构你的一些逻辑,使其成为DRYer。
首先,我会将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标头并做出相应的响应。如果您希望显示示例中的错误消息,请由您决定。
答案 1 :(得分:0)
让我们使用destroy动作示例:
我看到的常见方法是使控制器销毁动作简单如下:
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