Rails、respond_to 块和|格式|

cro*_*ill 0 ruby ruby-on-rails ruby-on-rails-4

Railsscaffold生成了以下内容:

respond_to do |format|
  if @student.save
    format.html { redirect_to @student, notice => 'Student was successfully created.' }
    format.json { render :show, status: :created, location: @student }
  else
    format.html { render :new }
    format.json { render json: @student.errors, status: :unprocessable_entity }
  end
end
Run Code Online (Sandbox Code Playgroud)

读完这篇文章后,我明白了它respond_to是如何工作的(某种程度上),但我不明白它format在做什么。难道不应该是其中一个 format.htmlformat.json而不是两者吗?这两行实际上在做什么?

format.html { render :new }
format.json { render json: @student.errors, status: :unprocessable_entity }
Run Code Online (Sandbox Code Playgroud)

是不是有什么暗示if在里面?是不是像

if (format == html) {}
if (format == json) {}
Run Code Online (Sandbox Code Playgroud)

旁注:为什么updaterequirerespond_to块 while showwill 处理/students/1.json/students/1根本没有任何逻辑?

max*_*max 5

format是一个产生 的局部变量。当您这样做时,您实际上是在注册格式的回调块。respond_to format.html {}

Rails 会检查注册的格式并尝试找到与请求中的 MIME 类型兼容的格式。如果没有处理程序,则会引发错误。

这可以解释为在一个语法糖之上使用语法糖。case(Ruby 相当于 switch 语句)。但这个类比并不完全准确,因为 Rails 在匹配请求类型方面做了一些工作。

此外,块内的代码不会在块format.html注册时执行(如果它只是一个条件语句),而是在respond_to完成或根本不执行(如果您使用例如 E-Tag 缓存)。

为什么 update 需要 respond_to 块,而 show 会在没有任何逻辑的情况下处理 /students/1.json 或 /students/1 ?

Rails 通过使用约定优于配置的方法并猜测操作的意图来处理许多操作。

def PostsController < ApplicationController
   def index
     # rails auto-magically fills in the controller with something 
     # like this
     @posts = Post.all
     respond_to do |format|
       format.html { render :index }
       format.json { render json: @posts }
     end 
   end

   def show
     # convention over configuration is awesome!
     @post = Post.find(params[:id])
     respond_to do |format|
       format.html { render :show }
       format.json { render json: @post }
     end
   end

   def new 
     @post = Post.new
     render :new
   end

   def edit 
     @post = Post.find(params[:id])
     render :edit
   end   
end
Run Code Online (Sandbox Code Playgroud)

Rails 假定存在与控制器同名的资源,并自动神奇地填充控制器操作。它还假设 中有一个视图app/views/posts/(:action).html.[erb|haml|slim|jbuilder]。这称为隐式渲染

这些评论大致显示了 actions Rails 尝试的内容。

它不会填充对数据进行操作的操作(创建、更新、销毁),因为实际的实现可能差异很大,并且很难做出有用的猜测。