简体   繁体   中英

How does respond_to and respond_with work in rails?

When there is

def some_action
  respond_to do |format|
    format.html {}
    format.js {}
    format.json { respond_with @objects}
  end
end

It seems like html line and the js line automatically serve up/call the file matching the action's name. And the html and the js are serve up one or the other, not both. Is this correct?

The json gets called if you have an ajax call in your js that got called, and it requests data, and these need data to respond with, right? Do I need it to respond to json and to js, or just one?

If you don't to respond_to, and omit all the types, does it by default respond to html and to js?

When I do respond_to in the controller, rather than a respond_to block within each action, does using respond_with @objects apply to any argument (:thml, :js, :xml, :json, etc)?

Alternate syntax:

class TheController < ApplicationController

  respond_to :html, :js, :json, only: [:some_action, :other_action]

  def some_action
    respond_with @objects
  end
end

How does the alternate syntax work?

If you use the alternate syntax, can you not respond differently to different types of requests? Do you have to do a respond_to block isntead of the alternate syntax if you want to respond differently? How do each of these cases address graceful degradation to html?

respond_with

For a given controller action, respond_with generates an appropriate response based on the mime-type requested by the client.

This basically means your controller will send the appropriate data on a request basis - for example, if you did the following:

#app/controllers/articles_controller.rb
Class ArticlesController < ApplicationController
   def show
       @article = Article.find params[:id]
       respond_with @article
   end
end

This would basically respond with the data from @article each time you send a request. If the request is in the json mime-type, it will come back as a JSON object; if it's an HTML request, it will come back with the HTML object on the show view

--

respond_to

Basically allows you to tailor the specific responses to different mime-types. If you send a JS request, you can manage the JS response etc

respond_to blocks inside the controller actions are very cumbersome, and only really meant for specific changes / edits to the response itself.

A much simpler way to handle the respond_to is to declare it at the top of the controller file, essentially telling Rails that every action will use the options defined in that method:

#app/controllers/your_controller.rb
Class YourController < ApplicationController
   respond_to :js, :json, :html #-> the same as using respond_to block for each action
end

请注意,在Rails 4中, respond_with功能已被提取到gem 'responders'https://github.com/plataformatec/responders )。

The cases of when you need/don't need each format.*whatever* line.

Normally, you don't need any of it. Rails by default looks for an html file (aka template) matching the action name under the view folder matching the controller's name.

I'm not sure when/why the json and html are sometimes paired together(like in the scaffold-generated code). Perhaps the json line is for turbolinks (please confirm/correct this). But I do know you use a respond_to block with various types of format lines when you want each type to behave differently (eg serve up 10 results at a time through js, but more results through html).

The js format is needed when you use remote: true in a form or link. This is because Using this remote: true disables the html template from being served up, and instead looks for a js file matching the action's name, and executes/renders that file. You don't actually need the respond to json line if you're doing things in js only.

Bonus hint: if your js files have js.erb, you can access the instance variables (how about local variables? please confirm/correct this) that you set in your action. This kind of makes sense because your *.js.erb file is technically a view. Views can access its corresponding actions' variables (hmm what about when vies get rendered from another controller?). So if you already have access to your action's variables in your js file, this can eliminate the need to make ajax calls or json calls in many situations.

I'm actually not sure when you need the json line when also using remote: true / javascript. explicit jQuery.ajax() method calls that want json data might warrant the use of the respond to json line.

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