suspenders 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
1
  module Suspenders
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
data/suspenders.gemspec CHANGED
@@ -27,9 +27,10 @@ rush to build something amazing; don't use it if you like missing deadlines.
27
27
  s.rdoc_options = ["--charset=UTF-8"]
28
28
  s.extra_rdoc_files = %w[README.md LICENSE]
29
29
 
30
- s.add_dependency('rails', '3.2.6')
31
- s.add_dependency('bundler', '>= 1.1')
30
+ s.add_dependency 'rails', '3.2.6'
31
+ s.add_dependency 'bundler', '>= 1.1'
32
+ s.add_dependency 'hub', '~> 1.10.2'
32
33
 
33
- s.add_development_dependency('cucumber', '~> 1.1.9')
34
- s.add_development_dependency('aruba', '~> 0.4.11')
34
+ s.add_development_dependency 'cucumber', '~> 1.1.9'
35
+ s.add_development_dependency 'aruba', '~> 0.4.11'
35
36
  end
@@ -5,20 +5,20 @@ gem 'formtastic'
5
5
  gem 'flutie'
6
6
  gem 'bourbon'
7
7
  gem 'airbrake'
8
- gem 'therubyracer'
9
8
 
10
9
  group :development do
11
10
  gem 'foreman'
12
11
  end
13
12
 
14
13
  group :development, :test do
14
+ gem 'guard'
15
+ gem 'guard-spork'
15
16
  gem 'rspec-rails', '~> 2.9.0'
16
17
  gem 'sham_rack'
17
18
  end
18
19
 
19
20
  group :test do
20
21
  gem 'cucumber-rails', '1.3.0'
21
- gem 'capybara-webkit', '~> 0.11.0'
22
22
  gem 'factory_girl_rails'
23
23
  gem 'bourne'
24
24
  gem 'database_cleaner'
@@ -0,0 +1,12 @@
1
+ guard 'spork' do
2
+ watch 'config/application.rb'
3
+ watch 'config/environment.rb'
4
+ watch %r{^config/environments/.*\.rb$}
5
+ watch %r{^config/initializers/.*\.rb$}
6
+ watch 'config/routes.rb'
7
+ watch 'Gemfile.lock'
8
+ watch 'spec/factories.rb'
9
+ watch 'spec/spec_helper.rb'
10
+ watch %r{^spec/support/.*\.rb$}
11
+ watch 'config/locales/.*'
12
+ end
@@ -1,316 +1,400 @@
1
- Rails app
2
- =========
1
+ Style Guide
2
+ ===========
3
3
 
4
- Rails 3.1 app running on Ruby 1.9.2 and deployed to Heroku's Cedar
5
- stack. It has an RSpec and Cucumber test suite which should be run
6
- before committing to the master branch.
7
-
8
- OS X preparation
9
- ----------------
10
-
11
- Postgres:
12
-
13
- brew install postgres --no-python
14
-
15
- Install Qt:
16
-
17
- brew install qt
18
-
19
- Debian preparation
20
- ------------------
21
-
22
- Install Qt:
23
-
24
- sudo apt-get install libqt4-dev libqtwebkit-dev
4
+ A guide for programming in style.
25
5
 
26
6
  Laptop setup
27
7
  ------------
28
8
 
29
- Getting the code:
9
+ Set up your laptop with [this script](https://github.com/thoughtbot/laptop)
10
+ and [these dotfiles](https://github.com/thoughtbot/dotfiles).
30
11
 
31
- git clone git@github.com:<account>/<repo>.git
12
+ Project setup
13
+ -------------
32
14
 
33
- Setting up Ruby:
15
+ Get the code.
34
16
 
35
- rvm install 1.9.2
36
- rvm use 1.9.2 --default
37
- gem install bundler git_remote_branch heroku taps
17
+ git clone git@github.com:organization/project.git
38
18
 
39
- App:
19
+ Set up the project's dependencies.
40
20
 
41
- cd app
21
+ cd project
42
22
  bundle --binstubs
43
23
  rake db:create
44
24
  rake db:schema:load
25
+ rake db:seed
45
26
 
46
- Configuration
47
- -------------
27
+ Add Heroku remotes for staging and production environments.
48
28
 
49
- Install the Heroku config plugin:
29
+ git remote add staging git@heroku.com:<app>-staging.git
30
+ git remote add production git@heroku.com:<app>-production.git
50
31
 
51
- heroku plugins:install git://github.com/ddollar/heroku-config.git
32
+ Use [Heroku config](https://github.com/ddollar/heroku-config) to get `ENV`
33
+ variables.
52
34
 
53
- Pull the Heroku config from staging:
35
+ heroku config:pull --app <app>-staging
54
36
 
55
- heroku config:pull --remote staging
37
+ Delete extra lines in `.env`, leaving only those needed for app to function
38
+ properly.
56
39
 
57
- You'll see credentials as config vars. Delete lines that don't apply.
40
+ BRAINTREE_MERCHANT_ID
41
+ BRAINTREE_PRIVATE_KEY
42
+ BRAINTREE_PUBLIC_KEY
43
+ S3_KEY
44
+ S3_SECRET
58
45
 
59
- Running tests
60
- -------------
46
+ Use [Foreman](http://goo.gl/oy4uw) to run the app locally.
61
47
 
62
- Run the whole test suite with:
48
+ foreman start
63
49
 
64
- rake
65
-
66
- Run individual features:
67
-
68
- cucumber features/visitor_signs_in.feature
69
-
70
- Run individual specs:
71
-
72
- rspec spec/models/user_spec.rb
50
+ It uses your `.env` file and `Procfile` to run processes just like Heroku's
51
+ [Cedar](https://devcenter.heroku.com/articles/cedar/) stack.
73
52
 
74
- Tab complete to make it even faster!
75
-
76
- When a spec or feature file has many specs in them, you sometimes want to run just what you're working on. In that case, specify a line number:
77
-
78
- rspec spec/models/user_spec.rb:8
79
- cucumber features/visitor_signs_in.feature:105
80
-
81
- Development process
82
- -------------------
83
-
84
- Choose a Github Issue.
53
+ Development
54
+ -----------
85
55
 
86
- Create a local feature branch off of master for development.
56
+ Create a local feature branch based off master.
87
57
 
88
58
  git checkout master
89
- git pull
90
- git checkout -b 123-feature-xyz
91
-
92
- Do work in your feature branch and commit the changes.
93
-
94
- git add -A
95
- git status
96
- git commit
97
-
98
- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
99
-
100
- [#123] Summary of changes
101
-
102
- * More information about commit
103
- * More information about commit
104
-
105
- A good commit message:
106
-
107
- * Prefixes the subject line with a Github Issue number.
108
- * Uses the present tense.
109
-
110
- Share your feature branch
111
-
112
- git push origin [branch]
59
+ git pull --rebase
60
+ git checkout -b feature-xyz
113
61
 
114
62
  Rebase frequently to incorporate upstream changes.
115
63
 
116
- git checkout master
117
- git pull
118
- git checkout [branch]
119
- git rebase master
64
+ git fetch origin
65
+ git rebase origin/master
120
66
  <resolve conflicts>
121
67
 
122
- Interactive rebase (squash) your commits (if necessary).
123
-
124
- git rebase -i master
125
-
126
- At this point the automated test suite must pass, and it must work and look good in your browser.
127
-
128
- Merge your branch back to master and push your changes.
129
-
130
- git checkout master
131
- git diff --stat master [branch]
132
- git merge [branch] --ff-only
133
- git push origin master
134
-
135
- Delete your remote feature branch.
136
-
137
- git push origin :[branch]
138
-
139
- Delete your local feature branch.
140
-
141
- git branch -d [branch]
142
-
143
- Close Github Issue.
144
-
145
- Deploying
146
- ---------
147
-
148
- Periodically use [pgbackups](http://devcenter.heroku.com/articles/pgbackups) to pull latest production data.
149
-
150
- Merge master into staging
68
+ When feature is complete and tests pass, commit the changes.
151
69
 
152
- git checkout master
153
- git reset --hard origin/master
154
- git pull
155
- git checkout staging
156
- git reset --hard origin/staging
157
- git log staging..master
158
- git diff --stat staging master
159
- git merge master
160
- git push origin staging
161
-
162
- Enable maintenance mode if required by database changes
70
+ rake
71
+ git add -A
72
+ git status
73
+ git commit -v
163
74
 
164
- heroku maintenance:on --app <%= app_name %>
75
+ Write a [good commit message](http://goo.gl/w11us).
165
76
 
166
- Deploy staging to Heroku
77
+ Present-tense summary under 50 characters
167
78
 
168
- git push <%= app_name %> staging:master
79
+ * More information about commit (under 72 characters).
80
+ * More information about commit (under 72 characters).
169
81
 
170
- Run new migrations if necessary
82
+ Share your branch.
171
83
 
172
- heroku rake db:migrate --app <%= app_name %>
84
+ git push origin [branch]
173
85
 
174
- Restart the dynos if migrations were run
86
+ Submit a [Github pull request](http://goo.gl/Kmdee).
175
87
 
176
- heroku restart --app <%= app_name %>
88
+ Ask for a code review in [Campfire](http://campfirenow.com).
177
89
 
178
- Disable maintenance mode if it's on
90
+ Code review
91
+ -----------
179
92
 
180
- heroku maintenance:off --app <%= app_name %>
93
+ A team member other than the author reviews the pull request.
181
94
 
182
- [Introspect](http://blog.heroku.com/archives/2011/6/24/the_new_heroku_3_visibility_introspection/) to make sure everything's OK
95
+ They make comments and ask questions directly on lines of code in the Github
96
+ web interface or in Campfire.
183
97
 
184
- watch heroku ps --app <%= app_name %>
98
+ For changes which they can make themselves, they check out the branch.
185
99
 
186
- [Rollback](http://devcenter.heroku.com/articles/releases) code if there was a problem
100
+ git checkout <branch>
101
+ rake db:migrate
102
+ rake
103
+ git diff staging..HEAD
187
104
 
188
- Production is the same:
105
+ They make small changes right in the branch, test the feature in browser,
106
+ run tests, commit, and push.
189
107
 
190
- * Use pgbackups to capture a DB backup
191
- * Merge staging into production
192
- * Enable maintenance mode if required by database changes
193
- * Deploy production to Heroku
194
- * Run new migrations if necessary
195
- * Restart dynos if migrations were run
196
- * Rollback code and use pgbackups to restore if there was a problem (turn on maintenance mode first if not already enabled)
197
- * Disable maintenance mode if it's on
198
- * Introspect to make sure everything's OK.
108
+ When satisfied, they comment on the pull request `Ready to squash and merge.`
199
109
 
200
- Heroku
110
+ Deploy
201
111
  ------
202
112
 
203
- To access data on Heroku:
113
+ If there are multiple commits in the branch, squash them.
204
114
 
205
- heroku console --app <%= app_name %>
115
+ git rebase -i staging/master
116
+ rake
206
117
 
207
- That will give you a Rails console. Run ActiveRecord queries from there.
118
+ View a list of new commits. View changed files. Merge branch into staging.
208
119
 
209
- To run a rake task on Heroku:
120
+ git checkout staging
121
+ git fetch staging
122
+ git reset --hard staging/master
123
+ git log staging..[branch]
124
+ git diff --stat [branch]
125
+ git merge [branch] --ff-only
210
126
 
211
- heroku rake db:migrate --app <%= app_name %>
127
+ Deploy to [Heroku](https://devcenter.heroku.com/articles/quickstart).
212
128
 
213
- Any rake task can be run with `heroku rake ...`
129
+ git push staging
214
130
 
215
- To dump staging or production data into your development environment:
131
+ Run migrations (if necessary).
216
132
 
217
- heroku db:pull --app <%= app_name %>
133
+ heroku run rake db:migrate --app <app>
218
134
 
219
- You will see progress bars for each DB index and table.
135
+ Restart the dynos if migrations were run.
220
136
 
221
- We can create a database backup at any time:
137
+ heroku restart --app <app>
222
138
 
223
- heroku pgbackups:capture --app <%= app_name %> --expire
139
+ [Introspect](http://goo.gl/tTgVF) to make sure everything's ok.
224
140
 
225
- View backups:
141
+ watch heroku ps --app <app>
226
142
 
227
- heroku pgbackups --app <%= app_name %>
143
+ Test the feature in browser.
228
144
 
229
- To destroy a backup:
145
+ Delete your remote feature branch.
230
146
 
231
- heroku pgbackups:destroy b003 --app <%= app_name %>
147
+ git push origin :[branch]
232
148
 
233
- Transfer production data to staging:
149
+ Delete your local feature branch.
234
150
 
235
- heroku pgbackups:capture --app <%= app_name %> --expire
236
- heroku pgbackups:restore DATABASE `heroku pgbackups:url --app <%= app_name %>` --app <%= app_name %>-staging
151
+ git branch -d [branch]
237
152
 
238
- More information in the [Dev Center](http://devcenter.heroku.com/articles/pgbackups).
153
+ Close pull request and comment `Merged.`
239
154
 
240
- To check the status of running app servers, background jobs, cron jobs, etc:
155
+ Deploy to production.
241
156
 
242
- heroku ps --app <%= app_name %>
157
+ git checkout production
158
+ git fetch production
159
+ git reset --hard production/master
160
+ git log production..staging
161
+ git diff --stat staging/master
162
+ git merge staging --ff-only
163
+ git push production
164
+ heroku run rake db:migrate --app <app>
165
+ heroku restart --app <app>
166
+ watch heroku ps --app <app>
243
167
 
244
- Programming
245
- -----------
168
+ Watch logs and metrics dashboards. If the feature is working, merge into master.
246
169
 
247
- We use [the thoughtbot style guide](http://build.thoughtbot.com/style-guide/) on this project. As of April 9, 2012:
170
+ git checkout master
171
+ git fetch origin
172
+ git log production..master
173
+ git merge production --ff-only
174
+ git push origin master
248
175
 
249
176
  Formatting
250
177
  ----------
251
178
 
252
- * Use 2 spaces for indentation. Don't use tabs.
253
- * In ERb files, indent both Ruby and HTML.
254
- * Include parenthesis in method definitions that take arguments.
255
- * Do not include parenthesis in method definitions that don't take arguments.
256
- * Do not use an empty line at the beginning or end of methods, blocks or conditionals.
179
+ * Delete trailing whitespace.
180
+ * Don't include spaces after `(`, `[` or before `]`, `)`.
181
+ * Don't vertically align tokens on consecutive lines.
182
+ * Include spaces around infix method invocations like `+` and `-`.
183
+ * Indent continued lines two spaces.
184
+ * Indent private methods equal to public methods.
185
+ * Limit lines to a maximum of 80 characters.
186
+ * Use 2 space indentation (no tabs) unless otherwise noted.
257
187
  * Use an empty line between methods, blocks and conditionals.
258
- * Don't line up assignments, arguments, or hash properties.
259
- * In Javascript, keep curly braces on the same line as an opening function, if, or other block.
260
- * Break up longer statements into multiple lines or methods. Most developers have editors at or below 120 columns.
261
- * If a single statement is split over several lines, indent all but the first line of the statement.
262
-
263
- Conditions
264
- ----------
265
-
266
- * Ternaries are harder to read than an if/else. Use an if/else.
267
- * Prefer `if` with positive conditions over `unless`.
268
- * Prefer `unless` over `if not`.
269
-
270
- Ruby Conventions
271
- ----------------
272
-
273
- * Define class methods using `def self.method` rather than `class << self` blocks.
274
- * Use curly braces for one-line blocks and `do`..`end` for multi-line blocks.
275
- * Prefer `&&` and `||` over `and` and `or`.
276
- * Use `each` instead of `for`.
277
- * Constants are all uppercase: CONSTANTS
278
- * Class and module names are camelcase: ClassNames
279
- * Method and variable names are underscored: `method_and_local_variables`
280
- * Methods that ask a question end in a question mark: asks_a_yes_no_question?
281
- * Mutating versions of methods end in an exclaimation point: gsub! for gsub
282
- * Exception-raising versions of methods end in an exclaimation point: save! for save
283
- * Always include a blank line before access specifiers like protected, public, and private.
284
- * Indent access specifiers equal to method definitions.
285
- * Indent protected and private methods equal to public methods.
286
-
287
- Javascript and Coffeescript Conventions
288
- ---------------------------------------
289
-
290
- * Constants are all uppercase: CONSTANTS
291
- * Prototype names are camel case: ClassNames
292
- * Function and variable names are camel case after the first letter: `functionAndVariableNames`
293
- * Internal functions and variable names start with an underscore: `_internalVariables`
294
- * Define functions that operate on the window or DOM in the scope of the window.
295
- * Initialize empty objects and hashes using `{}`.
296
- * Initialize arrays using `[]`.
297
- * Extending the base classes by adding functions onto their prototypes is acceptable.
188
+ * Use spaces around operators, after commas, colons and semicolons, around `{`
189
+ and before `}`.
298
190
 
299
191
  Naming
300
192
  ------
301
193
 
302
- * Reveal intent.
303
- * Be consistent.
304
- * Use verbs and nouns appropriately.
194
+ * Avoid abbreviations.
195
+ * Avoid Hungarian notiation (`szName`).
196
+ * Avoid types in names (`user_array`).
197
+ * Name background jobs with a `Job` suffix.
305
198
  * Name the enumeration parameter the singular of the collection.
306
- * Avoid one-letter variable names.
307
- * Avoid hungarian notiation or type information in names (for example, `szName` or `user_array`).
199
+ * Name variables, methods, and classes to reveal intent.
200
+ * Treat acronyms as words in names (`XmlHttpRequest` not `XMLHTTPRequest`),
201
+ even if the acronym is the entire name (`class Html` not `class HTML`).
202
+
203
+ Design
204
+ ------
308
205
 
309
- General Best Practices
310
- ----------------------
206
+ * Aggressively remove duplication during development.
207
+ * Avoid comments.
208
+ * Avoid global variables.
209
+ * Avoid long parameter lists.
210
+ * Be consistent.
211
+ * Don't duplicate the functionality of a built-in library.
212
+ * Don't swallow exceptions or "fail silently."
213
+ * Don't write code that guesses at future functionality.
214
+ * [Exceptions should be exceptional](http://rdd.me/yichhgvu).
215
+ * [Keep the code simple](http://rdd.me/ko2aqda2).
216
+ * Limit the number of collaborators of an object.
217
+ * Prefer composition over inheritance.
218
+ * Prefer small methods. One line is best.
219
+ * Prefer small objects with a single, well-defined responsibility.
220
+ * [Tell, don't ask](http://goo.gl/Ztawt).
221
+
222
+ Javascript
223
+ ----------
311
224
 
312
- * Prefer short methods. One line is best.
313
- * Avoid [Feature Envy](http://c2.com/cgi/wiki?FeatureEnvySmell). Tell, don't ask.
314
- * Exceptions should be exceptional.
315
- * Don't swallow exceptions or "fail silently".
316
- * Prefer readable code over comments.
225
+ * Define functions that operate on `window` or DOM in scope of `window`.
226
+ * Initialize arrays using `[]`.
227
+ * Initialize empty objects and hashes using `{}`.
228
+ * Use `CamelCase` for prototypes, `mixedCase` for variables and functions,
229
+ `SCREAMING_SNAKE_CASE` for constants, `_single_leading_underscore` for
230
+ private variables and functions.
231
+ * Use `data-` attributes to bind event handlers.
232
+ * Use the [module pattern](http://goo.gl/JDtHN) to control method visibility.
233
+
234
+ Ruby
235
+ ----
236
+
237
+ * Avoid conditional modifiers (lines that end with conditionals).
238
+ * Avoid hashes as optional parameters. Does the method do too much?
239
+ * Avoid including code and gems in source control that are specific to your
240
+ development machine or process. Examples: `.rvmrc`, `.swp`
241
+ * Avoid meta-programming.
242
+ * Avoid monkey-patching core classes.
243
+ * Avoid ternary operators (`boolean ? true : false`). Use multi-line `if`
244
+ instead to emphasize code branches.
245
+ * Define the project's [Ruby version in the
246
+ Gemfile](http://gembundler.com/man/gemfile.5.html#RUBY-ruby-).
247
+ * Prefer classes to modules when designing functionality that is shared by
248
+ multiple models.
249
+ * Prefer `detect`, not `find`, and `select`, not `find_all`, to avoid confusion
250
+ with ActiveRecord and keep `select`/`reject` symmetry.
251
+ * Prefer `map`, not `collect`, and `reduce`, not `inject`, due to symmetry and
252
+ familarity with mapping and reducing in other technologies.
253
+ * Use `_` for unused block parameters: `hash.map { |_, v| v + 1 }`
254
+ * Use `%{}` for single-line strings needing interpolation and double-quotes.
255
+ * Use `%w()`, not `['', '']`, for an array of words.
256
+ * Use `&&` and `||` for boolean expressions.
257
+ * Use `||=` freely.
258
+ * Use `{...}`, not `do..end`, for single-line blocks.
259
+ * Use `!` suffix for dangerous methods (modifies `self`).
260
+ * Use `?` suffix for predicate methods (return a boolean).
261
+ * Use `CamelCase` for classes and modules, `snake_case` for variables and
262
+ methods, `SCREAMING_SNAKE_CASE` for constants.
263
+ * Use `def` with parentheses when there are arguments.
264
+ * Use `do..end`, not `{...}`, for multi-line blocks.
265
+ * Use `each`, not `for`, for iteration.
266
+ * Use heredocs for multi-line strings.
267
+ * Use `/(?:first|second)/`, not `/(first|second)/`, when you don't need the
268
+ captured group.
269
+ * Use `private`, not `protected`, to indicate scope.
270
+ * Use `def self.method`, not `def Class.method` or `class << self`.
271
+ * Use `Set`, not `Array`, for arrays with unique elements. The lookup is faster.
272
+ * Use single-quotes for strings unless interpolating.
273
+
274
+ Rails
275
+ -----
276
+
277
+ * Avoid the `:except` option in routes.
278
+ * Avoid `member` and `collection` routes.
279
+ * Avoid Single Table Inheritance.
280
+ * Don't change a migration after it has been committed unless it cannot be
281
+ solved with another migration.
282
+ * Don't invoke a model's class directly from a view.
283
+ * Don't use SQL or SQL fragments (`where('inviter_id is not null')`) outside of
284
+ models.
285
+ * Keep the `db/schema.rb` under version control.
286
+ * Limit the number of instance variables shared between controller and view.
287
+ * Name initializers for their gem name. Example: `paperclip.rb`
288
+ * Order controller contents: filters, public methods, private methods.
289
+ * Order model contents: constants, attributes, associations, nested attributes,
290
+ named scopes, validations, callbacks, public methods, private methods.
291
+ * Prefer [decorators](http://goo.gl/yeF3X), not view helpers.
292
+ * Put all copy text in models, views, controllers, and mailers in
293
+ `config/locales`.
294
+ * Set `config.assets.initialize_on_precompile = false` in
295
+ `config/application.rb`.
296
+ * Set default values in the database.
297
+ * Use `_path`, not `_url`, for named routes everywhere except mailer views.
298
+ * Use `def self.method`, not the `named_scope :method` DSL.
299
+ * Use `I18n.t 'dot.separated.key'`, not `I18n.t :key,
300
+ :scope => [:dot, :separated]`.
301
+ * Use `has_and_belongs_to_many` if all you need is a join table. Do not include
302
+ an `id` or timestamps.
303
+ * Use namespaced locale lookup in views by prefixing a period: `t '.title'`.
304
+ * Use nested routes to express `belongs_to` relationships between resources.
305
+ * Use SQL, not `ActiveRecord` models, in migrations.
306
+ * Use the default `render 'partial'` syntax over `render partial: 'partial'`.
307
+ * Use the `:only` option to explicitly state exposed routes.
308
+
309
+ Database
310
+ --------
311
+
312
+ * Avoid multicolumn indexes in Postgres. It [combines multiple
313
+ indexes](http://goo.gl/pY3Po) efficiently.
314
+ * Create [indexes concurrently](https://gist.github.com/3186117) to avoid table
315
+ locks and [reduced performance](http://goo.gl/fi5ER) during deploys.
316
+ * Consider a [partial index](http://goo.gl/YC8Jt) for queries on booleans.
317
+ * Constrain most columns as [`NOT NULL`](http://goo.gl/0GeBr).
318
+ * Create a read-only [Heroku Follower](http://goo.gl/xWDMx) for your
319
+ production database. If a Heroku database outage occurs, Heroku can use the
320
+ follower to get your app back up and running faster.
321
+ * Index all foreign keys.
322
+ * Use a Heroku Follower database for analytics to limit reads on the primary
323
+ database.
324
+
325
+ Background Jobs
326
+ ---------------
327
+
328
+ * Define a `PRIORITY` constant at the top of the class.
329
+ * Define two public methods: `self.enqueue` and `perform`.
330
+ * Enqueue the job in `self.enqueue` [like this](http://goo.gl/C7e54).
331
+ * Put background jobs in `app/jobs`.
332
+ * Store IDs, not `ActiveRecord` objects for cleaner serialization, then re-find
333
+ the `ActiveRecord` object in the `perform` method.
334
+ * Subclass the job from `Struct.new(:something_id)`.
335
+ * Use [`Delayed::Job`](http://goo.gl/sRYju) for background jobs.
336
+
337
+ Email
338
+ -----
339
+
340
+ * Set `config.action_mailer.raise_delivery_errors = true` in the development
341
+ environment.
342
+ * Set `config.action_mailer.delivery_method = :test` in the test environment.
343
+ * Use one `ActionMailer` for the app. Name it `Mailer`.
344
+ * Use [SendGrid](http://goo.gl/Kxu9W) or [Amazon SES](http://goo.gl/A5jAA) to
345
+ deliver email in staging and production environments.
346
+ * Use [single recipient SMTP](http://goo.gl/FWdhG) in staging environment.
347
+ * Use the user's name in the `From` header and email in the `Reply-To` when
348
+ [delivering email on behalf of the app's users](http://goo.gl/5w1ck).
349
+
350
+ Gems
351
+ ----
352
+
353
+ * Use [AssetSync](http://goo.gl/m58tF) to serve assets from S3.
354
+ * Use [Bourbon](http://goo.gl/wpyee) for Sass mixins.
355
+ * Use [Bourne](http://goo.gl/lE7zH) for stubs and spies.
356
+ * Use [Braintree](http://goo.gl/mpWTp) for credit card processing.
357
+ * Use [Clearance](http://goo.gl/svPGo) for authentication.
358
+ * Use [Factory Girl](http://goo.gl/AB8bI) to set up test data.
359
+ * Use [Geocoder](http://goo.gl/CKnYF) for geocoding.
360
+ * Use [Haml](http://haml.info) for view templates.
361
+ * Use [Money](http://goo.gl/2CNfc) for money objects.
362
+ * Use [New Relic](http://goo.gl/F7Q56) for performance monitoring.
363
+ * Use [Paperclip](http://goo.gl/eSESD) for file uploads.
364
+ * Use [Thin](http://goo.gl/5Hlr) for serving web requests.
365
+ * Use [WebMock](http://goo.gl/BC1Ac) to disable real HTTP requests.
366
+
367
+ Testing
368
+ -------
369
+
370
+ * Avoid `its`, `let`, `let!`, `specify`, `subject`, and other DSLs. Prefer
371
+ explicitness and consistency.
372
+ * Disable real HTTP requests to external services with
373
+ `WebMock.disable_net_connect!`.
374
+ * Don't prefix `it` blocks with 'should'.
375
+ * Name outer `describe` blocks after the method under test. Use `.method`
376
+ for class methods and `#method` for instance methods.
377
+ * Order factories.rb: sequences, traits, factory definitions.
378
+ * Order factory definitions alphabetically by factory name.
379
+ * Order factory attributes: implicit attributes, newline, explicit attributes,
380
+ child factory definitions. Each section's attributes are alphabetical.
381
+ * Prefix `context` blocks names with 'given' when receiving input. Prefix with
382
+ 'when' in most other cases.
383
+ * Run specs with `--format documentation`.
384
+ * Test background jobs with a [`Delayed::Job` matcher](http://goo.gl/bzBlN).
385
+ * Use a `context` block for each execution path through the method.
386
+ * Use a [Fake](http://goo.gl/YR7Hh) to stub requests to external services.
387
+ * Use a `before` block to define phases of [Four Phase
388
+ Test](http://goo.gl/J9FiJ).
389
+ * Use integration tests to execute the entire app.
390
+ * Use non-[SUT](http://goo.gl/r5Ti2) methods in expectations when possible.
391
+ * Use one expectation per `it` block.
392
+ * Use [stubs and spies](http://goo.gl/EciDJ) (not mocks) in isolated tests.
393
+
394
+ Browsers
395
+ --------
396
+
397
+ * Don't support clients without Javascript.
398
+ * Don't support IE6.
399
+
400
+ [Always be learning](http://learn.thoughtbot.com).