Skip to content

Commit

Permalink
Merge branch 'chapter_16' into chapter_17
Browse files Browse the repository at this point in the history
* chapter_16:
  Mount forem engine within this application
  Update schema for delayed job
  Ticket notifications are now a background job
  Implement tidier caching for the tickets list on the projects page
  Add ETag and Last-Modified                support to ticket show page
  Add fragment caching to ticket listings on a project
  Added pagination for tickets

Conflicts:
	config/routes.rb
  • Loading branch information
radar committed Jun 17, 2011
2 parents 1b20400 + 16ee530 commit 691bcf9
Show file tree
Hide file tree
Showing 25 changed files with 223 additions and 25 deletions.
5 changes: 5 additions & 0 deletions Gemfile
Expand Up @@ -18,9 +18,14 @@ gem 'cancan'
gem 'paperclip', :git => "git://github.com/thoughtbot/paperclip.git"

gem 'searcher'
gem 'kaminari'

gem 'jquery-rails'
gem "oa-oauth", :require => "omniauth/oauth"
gem "delayed_job"

# gem "forem", :git => "git://github.com/radar/forem"
gem "ticketee-forem", :require => "forem", :path => "../forem"

gem 'sinatra'

Expand Down
11 changes: 11 additions & 0 deletions Gemfile.lock
Expand Up @@ -92,6 +92,11 @@ GIT
activesupport (>= 2.3.2)
cocaine (>= 0.0.2)

PATH
remote: ../forem
specs:
ticketee-forem (0.0.1)

GEM
remote: http://rubygems.org/
specs:
Expand Down Expand Up @@ -122,6 +127,7 @@ GEM
json (>= 1.4.6)
term-ansicolor (>= 1.0.5)
database_cleaner (0.6.7)
delayed_job (1.8.4)
diff-lcs (1.1.2)
dynamic_form (1.1.4)
email_spec (1.1.1)
Expand Down Expand Up @@ -150,6 +156,8 @@ GEM
thor (~> 0.14)
json (1.5.1)
json_pure (1.5.1)
kaminari (0.12.4)
rails (>= 3.0.0)
launchy (0.4.0)
configuration (>= 0.0.5)
rake (>= 0.8.1)
Expand Down Expand Up @@ -232,12 +240,14 @@ DEPENDENCIES
coffee-script
cucumber-rails!
database_cleaner
delayed_job
devise!
dynamic_form
email_spec
factory_girl
gmail
jquery-rails
kaminari
launchy
oa-oauth
paperclip!
Expand All @@ -251,3 +261,4 @@ DEPENDENCIES
sinatra
sprockets!
sqlite3
ticketee-forem!
2 changes: 1 addition & 1 deletion app/controllers/api/v2/tickets_controller.rb
Expand Up @@ -2,7 +2,7 @@ class Api::V2::TicketsController < Api::V2::BaseController
before_filter :find_project

def index
respond_with(@project.tickets)
respond_with(@project.tickets.page(params[:page]))
end

private
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/projects_controller.rb
Expand Up @@ -7,6 +7,9 @@ class ProjectsController < ApplicationController
:update,
:destroy]

# caches_action :show, :cache_path => (proc do
# project_path(params[:id]) + "/#{current_user.id}/#{params[:page] || 1}"
# end)

def index
@projects = Project.for(current_user).all
Expand All @@ -28,7 +31,7 @@ def create
end

def show
@tickets = @project.tickets
@tickets = @project.tickets.includes(:tags).page(params[:page]).per(50)
end

def edit
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/tickets_controller.rb
Expand Up @@ -32,6 +32,8 @@ def create
def show
@comment = @ticket.comments.build
@states = State.all
fresh_when :last_modified => @ticket.updated_at,
:etag => @ticket.to_s + current_user.id.to_s
end

def edit
Expand All @@ -56,6 +58,7 @@ def destroy

def search
@tickets = @project.tickets.search(params[:search])
@tickets = @tickets.page(params[:page]).per(50)
render "projects/show"
end

Expand Down
9 changes: 9 additions & 0 deletions app/jobs/comment_notifier_job.rb
@@ -0,0 +1,9 @@
class CommentNotifierJob < Struct.new(:comment_id)
def perform
comment = Comment.find(comment_id)
watchers = comment.ticket.watchers - [comment.user]
watchers.each do |user|
Notifier.comment_updated(comment, user).deliver
end
end
end
1 change: 1 addition & 0 deletions app/models/ticket.rb
@@ -1,4 +1,5 @@
class Ticket < ActiveRecord::Base
paginates_per 50
searcher do
label :tag, :from => :tags, :field => :name
label :state, :from => :state, :field => "name"
Expand Down
20 changes: 20 additions & 0 deletions app/sweepers/tickets_sweeper.rb
@@ -0,0 +1,20 @@
class TicketsSweeper < ActionController::Caching::Sweeper
observe Ticket
def after_create(ticket)
expire_fragments_for_project(ticket.project)
end

def after_update(ticket)
expire_fragments_for_project(ticket.project)
end

def after_destroy(ticket)
expire_fragments_for_project(ticket.project)
end

private

def expire_fragments_for_project(project)
expire_fragment(/projects\/#{project.id}\/.*?/)
end
end
11 changes: 5 additions & 6 deletions app/views/layouts/application.html.erb
Expand Up @@ -5,7 +5,6 @@
<%= stylesheet_link_tag "application" %>
<%= stylesheet_link_tag "projects" %>
<%= javascript_include_tag "application" %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tags %>

<style>
Expand All @@ -23,17 +22,17 @@
<%= value %>
</div>
<% end %>
<h1><%= link_to "Ticketee", root_path %></h1>
<h1><%= link_to "Ticketee", main_app.root_path %></h1>
<nav>
<%= admins_only do %>
<%= link_to "Admin", admin_root_path %><br>
<%= link_to "Admin", main_app.admin_root_path %><br>
<% end %>
<% if user_signed_in? %>
Signed in as <%= current_user %>
<%= link_to "Sign out", destroy_user_session_path %>
<%= link_to "Sign out", main_app.destroy_user_session_path %>
<% else %>
<%= link_to "Sign up", new_user_registration_path %>
<%= link_to "Sign in", new_user_session_path %>
<%= link_to "Sign up", main_app.new_user_registration_path %>
<%= link_to "Sign in", main_app.new_user_session_path %>

<br>
Or use <%= auth_providers(:twitter, :github) %>
Expand Down
19 changes: 11 additions & 8 deletions app/views/projects/show.html.erb
Expand Up @@ -18,11 +18,14 @@
<%= submit_tag "Search" %>
<% end %>
<ul id='tickets'>
<% @tickets.each do |ticket| %>
<li>
<%= render ticket.state if ticket.state %>
#<%= ticket.id %> - <%= link_to ticket.title, [@project, ticket] %>
</li>
<% end %>
</ul>
<% cache "projects/#{@project.id}/#{params[:page] || 1}" do %>
<%= paginate @tickets %>
<ul id='tickets'>
<% @tickets.each do |ticket| %>
<li>
<%= render ticket.state if ticket.state %>
#<%= ticket.id %> - <%= link_to ticket.title, [@project, ticket] %>
</li>
<% end %>
</ul>
<% end %>
16 changes: 16 additions & 0 deletions bin/rdiscount
@@ -0,0 +1,16 @@
#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'rdiscount' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)

require 'rubygems'
require 'bundler/setup'

load Gem.bin_path('rdiscount', 'rdiscount')
2 changes: 1 addition & 1 deletion config/database.yml
Expand Up @@ -17,7 +17,7 @@ test: &test

production:
adapter: sqlite3
database: db/production.sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000

Expand Down
2 changes: 1 addition & 1 deletion config/environments/development.rb
Expand Up @@ -11,7 +11,7 @@

# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_controller.perform_caching = true

# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
Expand Down
1 change: 1 addition & 0 deletions config/initializers/forem.rb
@@ -0,0 +1 @@
# Forem::Engine.user_class = User
4 changes: 2 additions & 2 deletions config/routes.rb
@@ -1,9 +1,9 @@
require 'heartbeat/application'

EdgeTicketee::Application.routes.draw do

mount Heartbeat::Application, :at => "/heartbeat"

mount Forem::Engine, :at => "/forem"

namespace :api do
namespace :v1 do
resources :projects do
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20110609020054_add_project_id_index_to_tickets.rb
@@ -0,0 +1,5 @@
class AddProjectIdIndexToTickets < ActiveRecord::Migration
def change
add_index :tickets, :project_id
end
end
10 changes: 10 additions & 0 deletions db/migrate/20110609123052_create_forem_topics.rb
@@ -0,0 +1,10 @@
class CreateForemTopics < ActiveRecord::Migration
def change
create_table :forem_topics do |t|
t.text :subject
t.integer :user_id

t.timestamps
end
end
end
11 changes: 11 additions & 0 deletions db/migrate/20110609123053_create_forem_posts.rb
@@ -0,0 +1,11 @@
class CreateForemPosts < ActiveRecord::Migration
def change
create_table :forem_posts do |t|
t.integer :topic_id
t.text :text
t.integer :user_id

t.timestamps
end
end
end
5 changes: 5 additions & 0 deletions db/migrate/20110609123054_add_posts_count_to_forem_topics.rb
@@ -0,0 +1,5 @@
class AddPostsCountToForemTopics < ActiveRecord::Migration
def change
add_column :forem_topics, :posts_count, :integer, :default => 0
end
end
18 changes: 17 additions & 1 deletion db/schema.rb
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20110608062135) do
ActiveRecord::Schema.define(:version => 20110609123054) do

create_table "assets", :force => true do |t|
t.string "asset_file_name"
Expand All @@ -37,6 +37,22 @@
t.integer "previous_state_id"
end

create_table "forem_posts", :force => true do |t|
t.integer "topic_id"
t.text "text"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "forem_topics", :force => true do |t|
t.text "subject"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "posts_count", :default => 0
end

create_table "permissions", :force => true do |t|
t.integer "user_id"
t.integer "thing_id"
Expand Down
21 changes: 21 additions & 0 deletions features/paginating_tickets.feature
@@ -0,0 +1,21 @@
Feature: Paginating tickets
In order to ease the load on the server
As the system
I want paginate ticket results

Background:
Given there is a project called "Internet Explorer"
Given there are the following users:
| email | password |
| user@ticketee.com | password |
And "user@ticketee.com" can view the "Internet Explorer" project
And I am signed in as them
And there are 100 tickets for this project

When I am on the homepage
And I follow "Internet Explorer"

Scenario: Viewing the second page
Then I should see 2 pages of pagination
When I follow "Next" within ".pagination .next"
Then I see page 2 of tickets for this project
9 changes: 9 additions & 0 deletions features/step_definitions/pagination_steps.rb
@@ -0,0 +1,9 @@
Then /^I should see (\d+) pages of pagination$/ do |number|
pages = all(".pagination .page")
pages.count.should eql(number.to_i)
end

Then /^I see page (\d+) of tickets for this project$/ do |number|
current_page = find(".pagination .current").text.strip
current_page.should eql(number)
end
8 changes: 8 additions & 0 deletions features/step_definitions/ticket_steps.rb
Expand Up @@ -9,4 +9,12 @@
ticket.tag!(tags) if tags
ticket.save
end
end

Given /^there are (\d+) tickets for this project$/ do |number|
number.to_i.times do |i|
@project.tickets.create!(:title => "Test",
:description => "Placeholder ticket.",
:user => @user)
end
end

0 comments on commit 691bcf9

Please sign in to comment.