Commit 233998c

mo khan <mo@mokhan.ca>
2016-05-03 20:56:45
cache api queries and paginate results.
1 parent a324c6f
app/controllers/concerns/pageable.rb
@@ -0,0 +1,16 @@
+module Pageable
+  extend ActiveSupport::Concern
+  DEFAULT_PER_PAGE=12
+
+  def page
+    (params[:page] || 1).to_i
+  end
+
+  def per_page
+    (params[:per_page] || DEFAULT_PER_PAGE).to_i
+  end
+
+  def paginate(items)
+    items.page(page).per(per_page)
+  end
+end
app/controllers/gyms_controller.rb
@@ -1,9 +1,10 @@
 class GymsController < ApplicationController
+  include Pageable
   before_action { @search_path = gyms_path }
   before_action only: [:index] { @remote_search = true }
 
   def index
-    @gyms = Gym.closest_to(current_session.location).search_with(params)
+    @gyms = paginate(Gym.closest_to(current_session.location).search_with(params))
   end
 
   def new
app/models/search.rb
@@ -1,11 +1,16 @@
 class Search
   def self.yelp(q, categories = [], city, page, per_page, &block)
-    city = city.present? ? city : 'Calgary'
-    Yelp.client.search(city, {
-      category_filter: categories.present? ? categories.join(',') : 'all',
-      limit: per_page,
-      offset: (page * per_page) - per_page,
-      term: q,
-    }).businesses.map(&block)
+    Rails.cache.fetch(q, expires_in: 1.hour) do
+      city = city.present? ? city : 'Calgary'
+      categories = categories.present? ? categories.join(',') : 'fitness'
+      Kaminari.paginate_array(
+        Yelp.client.search(city, {
+          category_filter: categories,
+          limit: per_page,
+          offset: (page * per_page) - per_page,
+          term: q,
+        }).businesses.map(&block)
+      )
+    end
   end
 end
app/views/gyms/_index.html.erb
@@ -1,28 +1,37 @@
-<table>
+<table role="grid">
+  <thead>
+  <tr>
+    <th>Name</th>
+    <th>Address</th>
+  </tr>
+  </thead>
+  <tbody>
   <% @gyms.each do |gym| %>
     <tr>
-    <td><%= gym.name %></td>
-    <td><%= gym.full_address %></td>
-    <td>
-      <%= link_to gym.location.try(:url) do %>
-        <i class="fa fa-map-marker" aria-hidden="true"></i>
-      <% end %>
-    </td>
-    <% if gym.new_record? %>
+      <td><%= gym.name %></td>
       <td>
-        <%= form_for(gym) do |form| %>
-          <%= form.hidden_field :name %>
-          <%= form.fields_for :location do |location_form| %>
-            <%= location_form.hidden_field :address %>
-            <%= location_form.hidden_field :city %>
-            <%= location_form.hidden_field :region %>
-            <%= location_form.hidden_field :country %>
-            <%= location_form.hidden_field :postal_code %>
+        <%= gym.full_address %>
+        <%= link_to gym.location.try(:url) do %>
+          <i class="fa fa-map-marker" aria-hidden="true"></i>
+        <% end %>
+      </td>
+      <td>
+        <% if gym.new_record? %>
+          <%= form_for(gym) do |form| %>
+            <%= form.hidden_field :name %>
+            <%= form.fields_for :location do |location_form| %>
+              <%= location_form.hidden_field :address %>
+              <%= location_form.hidden_field :city %>
+              <%= location_form.hidden_field :region %>
+              <%= location_form.hidden_field :country %>
+              <%= location_form.hidden_field :postal_code %>
+            <% end %>
+            <%= form.submit t(:add), class: "button tiny" %>
           <% end %>
-          <%= form.submit t(:save), class: "button tiny" %>
         <% end %>
       </td>
-    <% end %>
-  </tr>
-<% end %>
+    </tr>
+  <% end %>
+  </tbody>
 </table>
+<%= paginate @gyms, remote: true %>
app/views/kaminari/_first_page.html.erb
@@ -0,0 +1,3 @@
+<li>
+  <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote %>
+</li>
app/views/kaminari/_gap.html.erb
@@ -0,0 +1,1 @@
+<li aria-hidden="true" class="ellipsis"></li>
app/views/kaminari/_last_page.html.erb
@@ -0,0 +1,3 @@
+<li>
+  <%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote} %>
+</li>
app/views/kaminari/_next_page.html.erb
@@ -0,0 +1,3 @@
+<li>
+  <%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote %>
+</li>
app/views/kaminari/_page.html.erb
@@ -0,0 +1,7 @@
+<li class="<%= 'current' if page.current? %>">
+  <% if page.current? %>
+    <%= page %>
+  <% else %>
+    <%= link_to page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} %>
+  <% end %>
+</li>
app/views/kaminari/_paginator.html.erb
@@ -0,0 +1,15 @@
+<%= paginator.render do %>
+  <ul aria-label="Pagination" class="pagination" role="pagination">
+    <%= first_page_tag unless current_page.first? %>
+    <%= prev_page_tag unless current_page.first? %>
+    <% each_page do |page| %>
+      <% if page.left_outer? || page.right_outer? || page.inside_window? %>
+        <%= page_tag page %>
+      <% elsif !page.was_truncated? %>
+        <%= gap_tag %>
+      <% end %>
+    <% end %>
+    <%= next_page_tag unless current_page.last? %>
+    <%= last_page_tag unless current_page.last? %>
+  </ul>
+<% end %>
app/views/kaminari/_prev_page.html.erb
@@ -0,0 +1,3 @@
+<li>
+  <%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote %>
+</li>
config/locales/en.yml
@@ -20,6 +20,7 @@
 # available at http://guides.rubyonrails.org/i18n.html.
 
 en:
+  add: Add
   save: Save
   search: Search
   layouts:
Gemfile
@@ -34,6 +34,7 @@ source 'https://rubygems.org' do
   gem 'jbuilder', '~> 2.0'
   gem 'jquery-rails'
   gem 'jquery-turbolinks'
+  gem 'kaminari'
   gem 'meta_request', group: :development
   gem 'pg'
   gem 'phantomjs', group: [:development, :test]
Gemfile.lock
@@ -211,6 +211,9 @@ GEM
       railties (>= 3.1.0)
       turbolinks
     json (1.8.3)
+    kaminari (0.16.3)
+      actionpack (>= 3.0.0)
+      activesupport (>= 3.0.0)
     libv8 (3.16.14.13)
     loofah (2.0.3)
       nokogiri (>= 1.5.9)
@@ -453,6 +456,7 @@ DEPENDENCIES
   jbuilder (~> 2.0)!
   jquery-rails!
   jquery-turbolinks!
+  kaminari!
   meta_request!
   pg!
   phantomjs!