Ruby on rails 动态设置当前\u对象并避免使用before\u过滤器

Ruby on rails 动态设置当前\u对象并避免使用before\u过滤器,ruby-on-rails,ruby,Ruby On Rails,Ruby,假设我们有一个rails API。在许多控制器方法中,由于请求中的参数,我需要设置当前的_对象。然后,我可以在动作前设置一个,如: def set_current_object if My_object.exists? params[:id] @current_object = My_object.find params[:id] else render json: {error: 'Object not found'}.to_json, status:404 end

假设我们有一个rails API。在许多控制器方法中,由于请求中的参数,我需要设置当前的_对象。然后,我可以在动作前设置一个,如:

def set_current_object
  if My_object.exists? params[:id]
    @current_object = My_object.find params[:id]
  else
    render json: {error: 'Object not found'}.to_json, status:404
  end
end
这没关系。但是我想在我的控制器方法中动态设置当前对象。假设我在一个控制器中有一个show方法,需要使用当前的\u对象,如:

def show
  render json: {object_name: current_object.name}.to_json, status: 200
end
当前_对象将是一个助手方法,如:

def current_object
  if My_object.exists? params[:id]
    return My_object.find params[:id]
  else
    render json: {error: 'Object not found'}.to_json, status:404
  end
end

那么,如果我的对象存在?params[:id]为false我想发送404并停止我的控制器方法。就像这里写的,它显然不起作用。有什么建议吗?

你说得对。通常,您会将这种“延迟加载”实现为一种方法,该方法使用返回值

您只需修改
当前\u对象
辅助对象,以便在无法返回有效值时触发404错误。通常,您可以通过引发一个可识别的异常(如
ActiveRecord::RecordNotFound
)来完成此操作,并在控制器中使用
rescue\u from
子句处理此异常

class ApplicationController
  def current_object
    if My_object.exists? params[:id]
      # memozie the value so subsequent calls don't hit the database
      @current_object ||= My_object.find params[:id]
    else
      raise ActiveRecord::RecordNotFound  
    end
  end


  rescue_from ActiveRecord::RecordNotFound with: :show_404

  def show_404
    render json: {error: 'Object not found'}.to_json, status:404
  end
end
现在,由于在控制器层次结构的顶层处理
ActiveRecord::RecordNotFound
遵循了相当标准的Rails约定,因此现在可以相当大程度地清理
当前的\u对象
方法。不要检查记录是否存在,只需尝试按id查找该记录。如果该记录不存在,ActiveRecord将自动为您引发异常。事实上,您的整个
当前\u对象
方法应该是一行代码:

class ApplicationController
  def current_object
    @current_object ||= My_object.find(params[:id])
  end

  rescue_from ActiveRecord::RecordNotFound with: :show_404

  def show_404
    render json: {error: 'Object not found'}.to_json, status:404
  end
end

假设
My_object
是一个模型,如果只使用
find
,那么数据库中不存在的
params[:id]
将引发
ActiveRecord::RecordNotFound
错误,Rails的
ActionController::Base
将捕获异常并默认呈现404:

def current_object
  My_object.find params[:id]
end