Skip to content

Commit

Permalink
Add open and closed post counts to project
Browse files Browse the repository at this point in the history
A project should be able to return the number of open posts as well as
the number of closed posts.

This update adds two counter caches to the project model:
`open_posts_count` and `closed_posts_count`. These new attributes
reflect the count of posts matching the statuses of their namesake.

The [`test_after_commit`](https://github.com/grosser/test_after_commit)
gem is needed, as transactional fixtures are enabled and counter caches
are updated in an `after_commit` callback. See
[magnusvk/counter_culture#a-note-on-testing](https://github.com/magnusvk
/counter_culture#a-note-on-testing) for more info. This will no longer
be needed in Rails 5:
[rails/rails/pull/18458](rails/rails#18458).

To update existing counters, run the following:
```ruby
Post.counter_culture_fix_counts
https://github.com/magnusvk/counter_culture#manually-populating-counter-
cache-values
```

Resolves #323

Ignore localhost

Enable elasticsearch on circleci
  • Loading branch information
christopherstyles authored and joshsmith committed Jun 23, 2016
1 parent 0c7dd0d commit e7488ea
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Expand Up @@ -16,6 +16,7 @@ gem "aasm"
gem "analytics-ruby", require: "segment"
gem "aws-sdk"
gem "clearance"
gem "counter_culture"
gem "doorkeeper"
gem "faraday"
gem "github-markdown"
Expand Down Expand Up @@ -65,6 +66,7 @@ group :test do
gem "pusher-fake"
gem "rspec-sidekiq"
gem "shoulda-matchers", "3.0.1" # locked due to https://github.com/thoughtbot/shoulda-matchers/issues/880
gem "test_after_commit"
gem "vcr"
gem "webmock"
end
11 changes: 11 additions & 0 deletions Gemfile.lock
Expand Up @@ -59,6 +59,9 @@ GEM
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.4.0)
after_commit_action (1.0.1)
activerecord (>= 3.0.0)
activesupport (>= 3.0.0)
analytics-ruby (2.0.13)
annotate (2.7.0)
activerecord (>= 3.2, < 6.0)
Expand Down Expand Up @@ -98,6 +101,10 @@ GEM
concurrent-ruby (1.0.0)
connection_pool (2.2.0)
cookiejar (0.3.0)
counter_culture (0.2.1)
activerecord (>= 3.0.0)
activesupport (>= 3.0.0)
after_commit_action (~> 1.0.0)
crack (0.4.3)
safe_yaml (~> 1.0.0)
daemons (1.2.3)
Expand Down Expand Up @@ -319,6 +326,8 @@ GEM
sprockets (>= 3.0.0)
strip_attributes (1.8.0)
activemodel (>= 3.0, < 6.0)
test_after_commit (1.1.0)
activerecord (>= 3.2)
thin (1.6.4)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
Expand Down Expand Up @@ -350,6 +359,7 @@ DEPENDENCIES
capybara
clearance
codeclimate-test-reporter
counter_culture
database_cleaner
doorkeeper
dotenv-rails
Expand Down Expand Up @@ -391,6 +401,7 @@ DEPENDENCIES
sinatra
spring
strip_attributes
test_after_commit
vcr
webmock

Expand Down
7 changes: 7 additions & 0 deletions app/models/post.rb
Expand Up @@ -35,6 +35,13 @@ class Post < ActiveRecord::Base

acts_as_sequenced scope: :project_id, column: :number

counter_culture :project,
column_name: proc { |model| "#{model.status}_posts_count" },
column_names: {
["posts.status = ?", "open"] => "open_posts_count",
["posts.status = ?", "closed"] => "closed_posts_count"
}

validates :body, presence: true
validates :markdown, presence: true
validates :post_type, presence: true
Expand Down
27 changes: 15 additions & 12 deletions circle.yml
@@ -1,13 +1,16 @@
machine:
services:
- elasticsearch
deployment:
staging:
branch: develop
commands:
- git push git@heroku.com:code-corps-development.git $CIRCLE_SHA1:master
- heroku run rake db:migrate --app code-corps-development
- git push git@heroku.com:code-corps-staging.git $CIRCLE_SHA1:master
- heroku run rake db:migrate --app code-corps-staging
production:
branch: master
commands:
- git push git@heroku.com:code-corps.git $CIRCLE_SHA1:master
- heroku run rake db:migrate --app code-corps
staging:
branch: develop
commands:
- git push git@heroku.com:code-corps-development.git $CIRCLE_SHA1:master
- heroku run rake db:migrate --app code-corps-development
- git push git@heroku.com:code-corps-staging.git $CIRCLE_SHA1:master
- heroku run rake db:migrate --app code-corps-staging
production:
branch: master
commands:
- git push git@heroku.com:code-corps.git $CIRCLE_SHA1:master
- heroku run rake db:migrate --app code-corps
@@ -0,0 +1,6 @@
class AddOpenAndClosedPostsCountToProjects < ActiveRecord::Migration
def change
add_column :projects, :open_posts_count, :integer, null: false, default: 0
add_column :projects, :closed_posts_count, :integer, null: false, default: 0
end
end
4 changes: 3 additions & 1 deletion db/schema.rb
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20160621203648) do
ActiveRecord::Schema.define(version: 20160623044025) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -256,6 +256,8 @@
t.string "aasm_state"
t.text "long_description_body"
t.text "long_description_markdown"
t.integer "open_posts_count", default: 0, null: false
t.integer "closed_posts_count", default: 0, null: false
end

add_index "projects", ["organization_id"], name: "index_projects_on_organization_id", using: :btree
Expand Down
63 changes: 63 additions & 0 deletions spec/models/post_spec.rb
Expand Up @@ -141,6 +141,69 @@
end
end

describe "counter caches" do
context "on #project" do
let(:post) { create(:post) }
let(:project) { post.project }

context "with an 'open' status" do
before do
post.open!
project.reload
end

context "when creating" do
it "increments the open posts counter" do
expect(project.open_posts_count).to eq(1)
end
end

context "when destroying" do
it "decrements the open posts counter" do
expect { post.destroy! && project.reload }.
to change(project, :open_posts_count).from(1).to(0)
end
end

context "when changing" do
it "decrements the open posts counter" do
post.status = "closed"
expect { post.save! && project.reload }.
to change(project, :open_posts_count).from(1).to(0)
end
end
end

context "with a 'closed' status" do
before do
post.closed!
project.reload
end

describe "when creating" do
it "increments the closed posts counter" do
expect(project.closed_posts_count).to eq(1)
end
end

describe "when destroying" do
it "decrements the closed posts counter" do
expect { post.destroy! && project.reload }.
to change(project, :closed_posts_count).from(1).to(0)
end
end

describe "when changing" do
it "decrements the closed posts counter" do
post.status = "open"
expect { post.save! && project.reload }.
to change(project, :closed_posts_count).from(1).to(0)
end
end
end
end
end

describe "#save" do
it "renders markdown to body" do
post = build(:post, markdown: "# Hello World\n\nHello, world.")
Expand Down
2 changes: 1 addition & 1 deletion spec/rails_helper.rb
Expand Up @@ -41,7 +41,7 @@

VCR.configure do |config|
# Allow results to reported to codeclimate, bypassing VCR
config.ignore_hosts "codeclimate.com"
config.ignore_hosts "codeclimate.com", "localhost"
end

RSpec.configure do |config|
Expand Down

0 comments on commit e7488ea

Please sign in to comment.