Ruby on Rails: Layouts and Rendering May 4th, 2015

  • By default, controllers in Rails automatically render views with names that correspond to valid routes
  • The rule is that if you do not explicitly render something at the end of a controller action, Rails will automatically look for the action_name.html.erb template in the controller’s view path and render it
    • If you want to render the view that corresponds to a different template within the same controller, you can use render with the name of the view
      def update
       @book = Book.find(params[:id])
       if @book.update(book_params)
         redirect_to(@book)
       else
         render "edit"   # you can also use a symbol instead of a string  ... render :edit
       end
      end
    • You can render a template from an entirely different controller from the one that contains the action code (relative to app/views)…
      render "products/show"
  • You can render JSOn with render json: @product
  • Use the layout option to tell Rails to use a specific file as the layout for the current action:
    render layout: "special_layout"
  • There are six asset tag helpers in Rails…
    • auto_discovery_link_tag (for RSS feeds)
    • javascript_include_tag
    • stylesheet_link_tag
    • image_tag … e.g.<%= image_tag “home.gif”, alt: “Go Home”, id: “HomeImage”, class: “nav_bar” %>
    • video_tag
    • audio_tag
  • Yield
    • Within the context of a layout, yield identifies a section where content from the view should be inserted
      // Layout ...
      <html>
       <head>
         <%= yield :head %>
       </head>
       <body>
         <%= yield %>
       </body>
      </html>
      
      // View ...
      <% content_for :head do %>
       <title>A simple page</title>
      <% end %>
       
      <p>Hello, Rails!</p>
  • Partials
    • To render a partial as part of a view, you use the render method within the view
      // Render a file named _menu.html.erb at that point within the view being rendered
      <%= render "menu" %>
      
      // ... or ...
      <%= render "shared/ad_banner" %>
      
      // ... or a partial using its own layout ...
      <%= render partial: "link_area", layout: "graybar" %>
      • This would look for a partial named _link_area.html.erb and render it using the layout _graybar.html.erb
      • Note that layouts for partials follow the same leading-underscore naming as regular partials, and are placed in the same folder with the partial that they belong to (not in the master layouts folder)
    • You can pass-in local variables to make the partials even more powerful/customized …
      // new.html.erb
      <%= render partial: "form", locals: {zone: @zone} %>
      // ... or ...
      <%= render partial: "customer", object: @new_customer %>
      // ... or if you have an instance of a model to render in the partial use the shorthand ...
      <%= render @customer %>
      // ... or render partials once for each object in a collection ...
      <%= render partial: "product", collection: @products %>
      // ... or with a custom local variable
      <%= render partial: "product", collection: @products, as: :item %>
      
      // _form.html.erb
      <%= form_for(zone) do |f| %>
       <p>
         <b>Zone name</b><br>
         <%= f.text_field :name %>
       </p>
       <p>
         <%= f.submit %>
       </p>
      <% end %>

Resources