简体   繁体   English

缩写respond_to

[英]Abbreviating respond_to

I am currently working on a web application built on Rails 3 that heavily uses Ajax/REST for the client side. 我目前正在开发一个基于Rails 3的Web应用程序,它大量使用Ajax / REST作为客户端。 Thus, I often find myself writing controller actions like this: 因此,我经常发现自己编写这样的控制器动作:

def create
  if !params[:name] 
    respond_to do |format|
      format.html { render json: {}, status: :not_found }
      format.json { render json: {}, status: :not_found }
    end
    return
  end

  account = ...
  respond_to do |format|
    format.html { render json: account }
    format.json { render json: account }
  end
end

Nearly all of my actions are returning a json object in a success case or an error code. 几乎所有的动作都是在成功案例或错误代码中返回一个json对象。 However, I always have to write this verbose respond_to block and a return, if I want the action to return earlier. 但是,如果我希望操作先前返回,我总是必须编写这个详细的respond_to块和一个返回。

Instead I would like to use something like this instead, or a similar alternative: 相反,我想使用类似的东西,或类似的替代品:

def create
  if !params[:name] 
    throw :not_found
  end

  account = ...
  return account
end

How can this be done with Rails 3+ ? 如何使用Rails 3+完成这项工作?

Have a look into inherited_resources . 看看inherited_resources This will allow you to rewrite your controller as: 这将允许您将控制器重写为:

class SomeController < ApplicationController
  inherit_resources
  respond_to :html, :js, :json
end

That is it. 这就对了。 All of your create/read/update/delete methods will be accessible as usual. 您可以像往常一样访问所有创建/读取/更新/删除方法。 You can, as I have in the past, inherit from a master resources controller which uses inherited_resources, and then you can tweak the responses in a more general way. 您可以像过去一样继承自使用inherited_resources的主资源控制器,然后您可以更通用的方式调整响应。

class ResourcesController < ApplicationController
  inherit_resources
  respond_to :html, :js

  def create
    create! do |format|
      format.js do
        # generic code here for managing all create methods initiated via js
        # current model is avialbe via 'resource'
        # e.g 'resource.errors'
      end
    end
  end

Then simply inherit from that controller: 然后只需继承该控制器:

class SomeController < ResourcesController

end

This abstraction can be overkill for most purposes, but it has come in extremely handy when working 30 or 40 models which all require similar controllers. 对于大多数用途而言,这种抽象可能是过度的,但是当工作30或40个模型都需要类似的控制器时,它非常方便。

Inherited_resources offers many helpers for accessing the current model (referred to as resource) to facilitate dynamic references, so you can, for example, return relevant forms, or partials based on resource/model name. Inherited_resources提供了许多帮助程序来访问当前模型(称为资源)以促进动态引用,因此您可以根据资源/模型名称返回相关表单或部分。

To give you an idea of how to use this, you could return forms for the current controller by using the controller name in the parameters. 为了让您了解如何使用它,您可以使用参数中的控制器名称返回当前控制器的表单。 Should be noted that malformed controller names will not reach this method (as it will return 404), so it is safe to use: 需要注意的是,格式错误的控制器名称将无法访问此方法(因为它将返回404),因此可以安全使用:

  format.js do
    render "#{params[:controller]}/form"
  end

Best of all, you can override any of the methods yourself by defining them in a particular controller. 最重要的是,您可以通过在特定控制器中定义它们来自行覆盖任何方法。

If your are always returning json, you can ommit the respond_to block and write it like : 如果你总是返回json,你可以省略respond_to块并将它写成:

def create
  if !params[:name] 
    render json: {}, status: :not_found
    return
  end

  account = ...
  render json: account
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM