Rails scaffold
生成了以下内容:
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
阅读this后,我了解respond_to
的工作方式(有点),但我不知道format
正在做什么。不应该 format.html
或format.json
而不是 吗?这两条线实际上在做什么?
format.html { render :new }
format.json { render json: @student.errors, status: :unprocessable_entity }
那里有隐含的if
吗?是否像
if (format == html) {}
if (format == json) {}
旁注:为什么update
需要respond_to
阻止而show
会处理/students/1.json
或/students/1
而没有任何逻辑?
答案 0 :(得分:2)
format
是respond_to
yields的局部变量。执行format.html {}
时,实际上是在为格式注册回调块。
Rails会浏览已注册的格式,并尝试找到MIME type in the request的兼容格式。如果没有处理程序,则会引发错误。
这可以解释为在case
语句之上使用语法糖(Ruby等价于switch语句)。但这种类比并不完全准确,因为Rails在匹配请求类型方面做了一些工作。
当format.html
块被注册时(如果它只是一个条件语句),你的块内的代码也不会被执行,而是当respond_to
完成或者根本不完成时正在使用例如E-Tag缓存。
为什么update会在show处理时需要respond_to块 /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
Rails假设有一个与控制器同名的资源,并且 auto-magically 填充控制器操作。它还假设app/views/posts/(:action).html.[erb|haml|slim|jbuilder]
中有一个视图。
评论大致显示了rails尝试的动作。
它不会填充对数据进行操作的操作(创建,更新,销毁),因为实际实现可能会有很大差异,并且很难做出有用的猜测。
答案 1 :(得分:1)
嗯,这取决于请求的格式。如果请求要求服务器提供HTML,则会执行format.html
阻止,同样,如果请求需要JSON
格式,则会执行format.json
。
Rails将自动(阅读:神奇地)为您处理if (format == html)
部分。你所要做的就是填空。同样,您可以从format.xml
开始编写XML块。
对于附注,我认为你已经说过了。 update
方法不需要respond_to
阻止,而show
则需要update
阻止。原因很简单:show
方法可以更新模型,然后将您重定向到某个地方,而/students/1
将始终返回一些东西。在您的情况下,/students/1.json
将返回您在数据库中创建的第一个学生,并且响应将是HTML,而from nltk.corpus.reader import SyntaxCorpusReader
path = '/corpus/wsj'
filename = 'wsj1'
reader = SyntaxCorpusReader('/corpus/wsj','wsj1')
将返回相同的结果,但这次响应将是JSON。
答案 2 :(得分:0)
嗯,你可以用'foo'或'banana'或任何你想要的东西取代'format'。在这种情况下,它只是变量名称,因为response_to发送到您的块的变量正在传入传入的http请求的Accept标头所请求的格式。
有时您会在日志中看到422“不可接受”错误,因为您收到的请求带有一个不会请求您的应用知道的mime类型的Accept标头。
实际上,您的呼叫者应该使用浏览器或者是JSON使用者,发送正确的标头以接收来自样板的响应。