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.
- data/Gemfile.lock +3 -1
- data/NEWS.md +7 -0
- data/README.md +24 -7
- data/features/clearance_false.feature +10 -0
- data/features/github_repo.feature +8 -0
- data/features/heroku_true.feature +9 -0
- data/features/step_definitions/{shell_steps.rb → suspenders_steps.rb} +18 -0
- data/features/support/env.rb +2 -7
- data/features/support/fake_github.rb +21 -0
- data/features/support/fake_heroku.rb +1 -1
- data/features/webkit_false.feature +11 -0
- data/lib/suspenders/app_builder.rb +54 -19
- data/lib/suspenders/generators/app_generator.rb +38 -9
- data/lib/suspenders/version.rb +1 -1
- data/suspenders.gemspec +5 -4
- data/templates/Gemfile_additions +2 -2
- data/templates/Guardfile +12 -0
- data/templates/README.md.erb +318 -234
- data/templates/features_support_env.rb +16 -0
- metadata +32 -13
- data/GOALS +0 -2
- data/features/creating_a_heroku_app.feature +0 -9
- data/features/skipping_clearance.feature +0 -13
- data/features/step_definitions/gem_steps.rb +0 -5
- data/features/step_definitions/heroku_steps.rb +0 -3
data/lib/suspenders/version.rb
CHANGED
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
|
31
|
-
s.add_dependency
|
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
|
34
|
-
s.add_development_dependency
|
34
|
+
s.add_development_dependency 'cucumber', '~> 1.1.9'
|
35
|
+
s.add_development_dependency 'aruba', '~> 0.4.11'
|
35
36
|
end
|
data/templates/Gemfile_additions
CHANGED
@@ -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'
|
data/templates/Guardfile
ADDED
@@ -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
|
data/templates/README.md.erb
CHANGED
@@ -1,316 +1,400 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
Style Guide
|
2
|
+
===========
|
3
3
|
|
4
|
-
|
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
|
-
|
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
|
-
|
12
|
+
Project setup
|
13
|
+
-------------
|
32
14
|
|
33
|
-
|
15
|
+
Get the code.
|
34
16
|
|
35
|
-
|
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
|
-
|
19
|
+
Set up the project's dependencies.
|
40
20
|
|
41
|
-
cd
|
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
|
-
|
47
|
-
-------------
|
27
|
+
Add Heroku remotes for staging and production environments.
|
48
28
|
|
49
|
-
|
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
|
-
|
32
|
+
Use [Heroku config](https://github.com/ddollar/heroku-config) to get `ENV`
|
33
|
+
variables.
|
52
34
|
|
53
|
-
|
35
|
+
heroku config:pull --app <app>-staging
|
54
36
|
|
55
|
-
|
37
|
+
Delete extra lines in `.env`, leaving only those needed for app to function
|
38
|
+
properly.
|
56
39
|
|
57
|
-
|
40
|
+
BRAINTREE_MERCHANT_ID
|
41
|
+
BRAINTREE_PRIVATE_KEY
|
42
|
+
BRAINTREE_PUBLIC_KEY
|
43
|
+
S3_KEY
|
44
|
+
S3_SECRET
|
58
45
|
|
59
|
-
|
60
|
-
-------------
|
46
|
+
Use [Foreman](http://goo.gl/oy4uw) to run the app locally.
|
61
47
|
|
62
|
-
|
48
|
+
foreman start
|
63
49
|
|
64
|
-
|
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
|
-
|
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
|
56
|
+
Create a local feature branch based off master.
|
87
57
|
|
88
58
|
git checkout master
|
89
|
-
git pull
|
90
|
-
git checkout -b
|
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
|
117
|
-
git
|
118
|
-
git checkout [branch]
|
119
|
-
git rebase master
|
64
|
+
git fetch origin
|
65
|
+
git rebase origin/master
|
120
66
|
<resolve conflicts>
|
121
67
|
|
122
|
-
|
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
|
-
|
153
|
-
git
|
154
|
-
git
|
155
|
-
git
|
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
|
-
|
75
|
+
Write a [good commit message](http://goo.gl/w11us).
|
165
76
|
|
166
|
-
|
77
|
+
Present-tense summary under 50 characters
|
167
78
|
|
168
|
-
|
79
|
+
* More information about commit (under 72 characters).
|
80
|
+
* More information about commit (under 72 characters).
|
169
81
|
|
170
|
-
|
82
|
+
Share your branch.
|
171
83
|
|
172
|
-
|
84
|
+
git push origin [branch]
|
173
85
|
|
174
|
-
|
86
|
+
Submit a [Github pull request](http://goo.gl/Kmdee).
|
175
87
|
|
176
|
-
|
88
|
+
Ask for a code review in [Campfire](http://campfirenow.com).
|
177
89
|
|
178
|
-
|
90
|
+
Code review
|
91
|
+
-----------
|
179
92
|
|
180
|
-
|
93
|
+
A team member other than the author reviews the pull request.
|
181
94
|
|
182
|
-
|
95
|
+
They make comments and ask questions directly on lines of code in the Github
|
96
|
+
web interface or in Campfire.
|
183
97
|
|
184
|
-
|
98
|
+
For changes which they can make themselves, they check out the branch.
|
185
99
|
|
186
|
-
|
100
|
+
git checkout <branch>
|
101
|
+
rake db:migrate
|
102
|
+
rake
|
103
|
+
git diff staging..HEAD
|
187
104
|
|
188
|
-
|
105
|
+
They make small changes right in the branch, test the feature in browser,
|
106
|
+
run tests, commit, and push.
|
189
107
|
|
190
|
-
|
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
|
-
|
110
|
+
Deploy
|
201
111
|
------
|
202
112
|
|
203
|
-
|
113
|
+
If there are multiple commits in the branch, squash them.
|
204
114
|
|
205
|
-
|
115
|
+
git rebase -i staging/master
|
116
|
+
rake
|
206
117
|
|
207
|
-
|
118
|
+
View a list of new commits. View changed files. Merge branch into staging.
|
208
119
|
|
209
|
-
|
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
|
-
|
127
|
+
Deploy to [Heroku](https://devcenter.heroku.com/articles/quickstart).
|
212
128
|
|
213
|
-
|
129
|
+
git push staging
|
214
130
|
|
215
|
-
|
131
|
+
Run migrations (if necessary).
|
216
132
|
|
217
|
-
heroku db:
|
133
|
+
heroku run rake db:migrate --app <app>
|
218
134
|
|
219
|
-
|
135
|
+
Restart the dynos if migrations were run.
|
220
136
|
|
221
|
-
|
137
|
+
heroku restart --app <app>
|
222
138
|
|
223
|
-
|
139
|
+
[Introspect](http://goo.gl/tTgVF) to make sure everything's ok.
|
224
140
|
|
225
|
-
|
141
|
+
watch heroku ps --app <app>
|
226
142
|
|
227
|
-
|
143
|
+
Test the feature in browser.
|
228
144
|
|
229
|
-
|
145
|
+
Delete your remote feature branch.
|
230
146
|
|
231
|
-
|
147
|
+
git push origin :[branch]
|
232
148
|
|
233
|
-
|
149
|
+
Delete your local feature branch.
|
234
150
|
|
235
|
-
|
236
|
-
heroku pgbackups:restore DATABASE `heroku pgbackups:url --app <%= app_name %>` --app <%= app_name %>-staging
|
151
|
+
git branch -d [branch]
|
237
152
|
|
238
|
-
|
153
|
+
Close pull request and comment `Merged.`
|
239
154
|
|
240
|
-
|
155
|
+
Deploy to production.
|
241
156
|
|
242
|
-
|
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
|
-
|
245
|
-
-----------
|
168
|
+
Watch logs and metrics dashboards. If the feature is working, merge into master.
|
246
169
|
|
247
|
-
|
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
|
-
*
|
253
|
-
*
|
254
|
-
*
|
255
|
-
*
|
256
|
-
*
|
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
|
-
*
|
259
|
-
|
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
|
-
*
|
303
|
-
*
|
304
|
-
*
|
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
|
-
*
|
307
|
-
*
|
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
|
-
|
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
|
-
*
|
313
|
-
*
|
314
|
-
*
|
315
|
-
*
|
316
|
-
|
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).
|