美文网首页
4. Working with Controllers - 4.

4. Working with Controllers - 4.

作者: 介可能是只乌龟 | 来源:发表于2016-04-21 08:52 被阅读0次

    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.

    相关文章

      网友评论

          本文标题:4. Working with Controllers - 4.

          本文链接:https://www.haomeiwen.com/subject/dwqnlttx.html