Skip to content

Backend Training: Collection Rendering

Nelson Lee edited this page Nov 30, 2017 · 4 revisions

🔖 : Collections, Partials

Rails provides a standard structure when rendering collection of records. Let's begin by modifying our controller actions.

Adding Posts To home#index

# app/controllers/home_controller.rb
class HomeController < ApplicationController

  def index
    @posts = Post.published.by_published_date.
             limit(3)
  end

  def pricing; end

end

Add a partial for news - app/views/posts/_post.slim, and copy and paste a single post HTML markup from app/views/home/index.slim

# app/views/posts/_post.slim
.col-sm-6.col-md-4
  .thumbnail
    = holder_tag '300x150', 'Sample Image', '', class: 'img-responsive'
    .caption
      p= post.content
      p
        a.btn.btn-primary[href="#" role="button"]
          | Button

Change app/views/home/index.slim to...

# app/views/home/index.slim
section.jumbotron[id='hero']
  ......

section[id='about']
  ......

section[id='news']
  .container
    .row.text-center
      .col-md-12
        h2= t('.news.title')
    .row
      = render @posts

section[id='faqs']
  ......

Refresh the browser Command ⌘+r, and you should see the posts are now displaying.

Adding Faqs To home#index

# app/controllers/home_controller.rb
class HomeController < ApplicationController

  def index
    @posts = Post.published.by_published_date.
             limit(3)
    @faqs = Faq.by_position
  end

  def pricing; end

end

Add a partial for news - app/views/faqs/_faq.slim, and copy and paste a single faq HTML markup from app/views/home/index.slim

# app/views/faqs/_faq.slim
.panel.panel-default
  .panel-heading[id="heading_#{dom_id(faq)}" role="tab"]
    h4.panel-title
      a[role="button" data-toggle="collapse" data-parent="#faqs" href="##{dom_id(faq)}" aria-expanded=faq_counter.zero? aria-controls=dom_id(faq)]
        = "#{faq_counter + 1}. #{faq.question}"
  .panel-collapse.collapse[id=dom_id(faq) class=(faq_counter.zero? ? 'in' : nil) role="tabpanel" aria-labelledby="heading_#{dom_id(faq)}"]
    .panel-body
      == faq.answer

p.s. == faq.answer means render raw html.

Change app/views/home/index.slim to...

# app/views/home/index.slim
section.jumbotron[id='hero']
  ......

section[id='about']
  ......

section[id='news']
  ......

section[id='faqs']
  .container
    .row.text-center
      .col-md-12
        h2= t('.faqs.title')
    .row
      .col-md-12
        #faqs.panel-group[role="tablist" aria-multiselectable="true"]
          = render @faqs

Refresh the browser Command ⌘+r, you should see the faqs are now displaying.

Adding Faqs To faqs#index

Let's create a faqs_controller

$ rails g controller faqs

Change the faq controller

# app/controllers/faqs_controller.rb
class FaqsController < ApplicationController

  def index
    @faqs = Faq.by_position
  end

end

Add routes for faq controller

Rails.application.routes.draw do
  ......

  resources :faqs, only: %i[index]

  get '/pricing' => 'home#pricing', as: :pricing

  root 'home#index'
end

Check to see if the routes for faqs are there..

$ rails routes | grep faqs
      faqs GET        /faqs(.:format)       faqs#index

And you should see that faqs#index has been added to the routes list. p.s. grep means filter by %{keyword}

Create app/views/faqs/index.slim and add...

# app/views/faqs/index.slim
section[id='faqs']
  .container
    .row.text-center
      .col-md-12
        h2= t('.title')
    .row
      .col-md-12
        #faqs.panel-group[role="tablist" aria-multiselectable="true"]
          = render @faqs

Add faq link to app/views/components/_navbar.slim

nav.navbar.navbar-default
  .container
    .navbar-header
      ......
    .collapse.navbar-collapse[id='main-nav']
      ul.nav.navbar-nav.navbar-right
        ......
        li= link_to t('.faqs'), faqs_path

Add translations

# config/localse/en.yml
en:
  activerecord:
    ......

  components:
    navbar:
      home: HOME
      about: ABOUT
      pricing: PRICING
      pricing/basic: Basic Package
      pricing/advance: Advance Package
      faqs: FAQS
    footer:
      copyright: '%{year} © Clever Banana Studios Inc. All Rights Reserved.'

  home:
    ......

  faqs:
    index:
      title: FAQs

Now click on the faq link you should be able to go to /faqs and see the list of faqs. faq#index

Let's commit and move on..

$ git add -A
$ git commit -m 'Post and Faq rendering collections'

The overcommit hook will fail for faq_decorator and faq_controller_spec.

Let's fix them

# app/decorators/faq_decorator.rb
# Decorates Faqs
class FaqDecorator < Draper::Decorator

  delegate_all

end
# spec/controllers/faqs_controller_spec.rb
require 'rails_helper'

RSpec.describe FaqsController, type: :controller do
  pending "add some examples to (or delete) #{__FILE__}"
end

Let's commit again and move on..

$ git add -A
$ git commit -m 'Post and Faq rendering collections'

↪️ Next Section: Pagination