Rails模式的行动(更新,删除等)&错误检查

时间:2014-05-04 17:35:43

标签: ruby-on-rails ruby restful-url

我是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

2 个答案:

答案 0 :(得分:2)

我会从个别行动中重构你的一些逻辑,使其成为DRYer。

首先,我会将fetch_team的支票移到before_action过滤器中。这样,您可以让Rails为showupdatedestroy等多项操作运行它。

当你致电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

继续删除