简体   繁体   中英

Abbreviating respond_to

I am currently working on a web application built on Rails 3 that heavily uses Ajax/REST for the client side. 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. However, I always have to write this verbose respond_to block and a return, if I want the action to return earlier.

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+ ?

Have a look into 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.

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.

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.

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:

  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 :

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

  account = ...
  render json: account
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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