4. Working with Controllers - 4.3 Render unto View

4.3 Render unto View

By the way, make sure you reload the console when you make changes—it doesn’t react to changes in sourcecode automatically. The easiest way to reload the console is simply to type reload!. But be aware that anyexisting instances of Active Record objects that you’re holding on to will also need to be reloaded (using theirindividual reload methods). Sometimes it’s simpler to just exit the console and start it up again.

4.3.1 When in Doubt, Render

Rails knows that when it gets a request for the index action of the demo controller, what really matters is handing something back to the server. So if there’s no index action in the controller file, Rails shrugs and says, “Well, let’s just assume that if there were an index action, it would be empty anyway, and I’d just render index.html.haml. So that’s what I’ll do.”

class DemoController < ApplicationController 
  def index
  end
end

What you learn from seeing the empty action is that, at the end of every controller action, if nothing else is specified, the default behavior is to render the template whose name matches the name of the controller and action, which in this case means app/views/demo/index.html.haml.
In other words, every controller action has an implicit render command in it. And render is a real method. You could write the preceding example like this:

def index
  render `demo/index`
end

You don’t have to, though, because it’s assumed that it’s what you want, and that is part of what Rails people are talking about when they discuss convention over configuration. Don’t force the developer to add code to accomplish something that can be assumed to be a certain way.

4.3.2 Explicit Rendering

If a controller action doesn’t want to render its default template, it can render a different one by calling the render method explicitly. Any template file in the app/views directory tree is available. (Actually, that’s not exactly true. Any template on the whole system is available!)

4.3.3 Rendering Another Action's Template

A common reason for rendering an entirely different template is to redisplay a form, when it gets submittedwith invalid data and needs correction.

class EventController < ActionController::Base 
  def new
    # This (empty) action renders the new.html.haml template, which
    # contains the form for inputting information about the new
    # event record and is not actually needed.
  end

  def create
    # This method processes the form input. The input is available via 
    # the params hash, in the nested hash keyed to :event
    @event = Event.new(params[:event])
    if @event.save
        # ignore the next line for now
      redirect_to dashboard_path, notice: "Event created!" 
    else
      render action: 'new' # doesn't execute the new method! 
    end
  end 
end

Note that the template itself doesn’t “know” that it has been rendered by the create action rather than the new action. It just does its job: It fills out and expands and interpolates, based on the instructions it contains and the data (in this case, @event) that the controller has passed to it.

4.3.4 Rendering a Different Template Altogether

In a similar fashion, if you are rendering a template for a different action, it is possible to render any template in your application by calling render with a string pointing to the desired template file. The render method is very robust in its ability to interpret which template you’re trying to refer to.

render template: '/products/index.html.haml'

# It’s not necessary to pass a hash with :template, because it’s the default option. 
render '/products/index.html.haml'
render 'products/index.html.haml'
render 'products/index.html'
render 'products/index'
render 'index'
render :index

The :template option only works with a path relative to the template root (app/views, unless you changed it, which would be extremely unusual).

4.3.5 Rendering a Partial Template

Another option is to render a partial template (usually referred to simply as a partial). Usage of partial templates allows you to organize your template code into small files. Partials can also help you to avoid clutter and encourage you to break your template code up into reusable modules.

There are a few ways to trigger partial rendering. The first, and most obvious, is using the :partial option to explicitly specify a partial template. Rails has a convention of prefixing partial template file names with an underscore character, but you never include the underscore when referring to partials.

render partial: 'product'#rendersapp/views/products/_product.html.haml
render partial: 'shared/product'#rendersapp/views/shared/_product.html.haml
render partial: @product
render @product 
render 'product'

4.3.6 Rendering Inline Template Code

Occasionally, you need to send the browser the result of translating a snippet of template code, too small to merit its own partial. I admit that this practice is contentious, because it is a flagrant violation of proper separation of concerns between the MVC layers.

Rails treats the inline code exactly as if it were a view template. The default type of view template processing is ERb, but passing an additional :type option allows you to choose Haml.

render inline: "%span.foo#{@foo.name}", type:"haml"

4.3.7 Rendering Text

What if you simply need to send plain text back to the browser, particularly when responding to Ajax and certain types of web service requests?

render text: 'Submission accepted'

Unfortunately, if you don’t pass an additional :content_type option, Rails will default the response MIME
type to text/html, rather than text/plain. The solution is to be explicit about what you want.

render text: 'Submission accepted',  content_type: 'text/plain'

4.3.8 Rendering Other Types of Structured Data

4.8.1 :json

JSON is a small subset of JavaScript selected for its usability as a lightweight data-interchange format.

render json: @record

As long as the parameter responds to to_json, Rails will call it for you, which means you don’t have to call
it yourself with ActiveRecord objects.

Any additional options passed to render :json are also included in the invocation of to_json.

render json: @projects, include: tasks

Additionally, if you’re doing JSONP, you can supply the name of a callback function to be invoked in the
browser when it gets your response. Just add a :callback option with the name of a valid JavaScript method.

render json: @record, callback: 'updateRecordsDisplay'

4.8.2 :xml

Active Record also has built-in support for conversion to XML, as in the following example:

render xml: @record

As long as the parameter responds to to_xml, Rails will call it for you, which means you don’t have to call it
yourself with ActiveRecord objects.

Any additional options passed to render :xml are also included in the invocation of to_xml.

render xml: @projects, include: :tasks

4.3.9 Rendering Nothing

On rare occasions, you don’t want to render anything at all. (To avoid a bug in Safari, rendering nothing actually means sending a single space character back to the browser.)

head :unauthorized

The head method allows you to return a response with no content, and a specific status code. You could achieve the same result as the above code snippet, by calling render nothing: true and explicitly providing a status.

render nothing: true, status: 401

The head method also accepts an options hash, that is interpreted as header names and values to be included with the response. To illustrate, consider the following example which returns an empty response with a status of 201, and also sets the Location header:

head :created, location: auction_path(@auction)

4.3.10 Rendering Options

Most calls to the render method accept additional options. Here they are in alphabetical order.

:content_type

All content flying around the web is associated with a MIME type. For instance, HTML content is labeled with a content-type of text/html. However, there are occasions where you want to send the client something other than HTML. Rails doesn’t validate the format of the MIME identifier you pass to the :content_type option, so make sure it is valid.

:layout

By default, Rails has conventions regarding the layout template it chooses to wrap your response. The :layout option allows you to specify whether you want a layout template to be rendered if you pass it a boolean value, or the name of a layout template, if you want to deviate from the default.

render layout: false # disable layout template
render layout: 'login' # a template app/views/layouts is assumed

:status

The HTTP protocol includes many standard status codes4 indicating a variety of conditions in response to a client’s request. Rails will automatically use the appropriate status for most common cases, such as 200 OK for a successful request.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,287评论 0 23
  • 享受每一个当下,就是最好的年龄。 1 90后已经不再是年轻的代名词,不信,你算(虚岁) 1990年,27岁; 19...
    愈姑娘阅读 8,058评论 260 200
  • 【一】9.9,CVTE: 【二】9.20,联友科技: 【三】10.11,全志科技: 【四】10.12,龙旗集团: ...
    _minimal阅读 264评论 0 0
  • 关键词:昌盛,祝福,神的旨意 放眼未来,纵横今生,于我们而言,日子是平静安稳的。殊不知,官僚份子与反腐人员在某个时...
    Naomisky阅读 115评论 0 0