Skip to content

Commit 0cac9c6

Browse files
committed
Merge pull request #1 from thoughtbot/master
merging with source
2 parents 71aa65f + 5deeaaa commit 0cac9c6

File tree

38 files changed

+1947
-130
lines changed

38 files changed

+1947
-130
lines changed

.hound.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
javascript:
2+
enabled: false
3+
jscs:
4+
enabled: true
5+
config_file: style/javascript/.jscsrc
6+
ruby:
7+
enabled: true
8+
config_file: style/ruby/.rubocop.yml
9+
scss:
10+
enabled: true
11+
config_file: style/sass/.scss-lint.yml

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ Guides
33

44
Guides for getting things done, programming well, and programming in style.
55

6+
* [Best Practices](/best-practices)
7+
* [Code Review](/code-review)
8+
* [How to](/how-to)
69
* [Protocol](/protocol)
10+
* [Communication](/protocol/communication)
711
* [Git](/protocol/git)
8-
* [Rails](/protocol/rails)
912
* [iOS](/protocol/ios)
1013
* [Open Source](/protocol/open-source)
11-
* [Code Review](/code-review)
12-
* [Best Practices](/best-practices)
14+
* [Product Review](/protocol/product-review)
15+
* [Rails](/protocol/rails)
16+
* [Security](/security)
1317
* [Style](/style)
1418

1519
High level guidelines:

best-practices/README.md

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ General
1111
* Don't duplicate the functionality of a built-in library.
1212
* Don't swallow exceptions or "fail silently."
1313
* Don't write code that guesses at future functionality.
14-
* [Exceptions should be exceptional].
14+
* Exceptions should be exceptional.
1515
* [Keep the code simple].
1616

17-
[Exceptions should be exceptional]: http://www.readability.com/~/yichhgvu
1817
[Keep the code simple]: http://www.readability.com/~/ko2aqda2
1918

2019
Object-Oriented Design
@@ -64,6 +63,7 @@ Ruby Gems
6463
Rails
6564
-----
6665

66+
* [Add foreign key constraints][fkey] in migrations.
6767
* Avoid bypassing validations with methods like `save(validate: false)`,
6868
`update_attribute`, and `toggle`.
6969
* Avoid instantiating more than one object in controllers.
@@ -87,6 +87,8 @@ Rails
8787
patch level for a project.
8888
* Use `_url` suffixes for named routes in mailer views and [redirects]. Use
8989
`_path` suffixes for named routes everywhere else.
90+
* Use a [class constant rather than the stringified class name][class constant in association]
91+
for `class_name` options on ActiveRecord association macros.
9092
* Validate the associated `belongs_to` object (`user`), not the database column
9193
(`user_id`).
9294
* Use `db/seeds.rb` for data that is required in all environments.
@@ -97,17 +99,24 @@ Rails
9799
* Prefer `Time.zone.parse("2014-07-04 16:05:37")` over `Time.parse("2014-07-04 16:05:37")`
98100
* Use `ENV.fetch` for environment variables instead of `ENV[]`so that unset
99101
environment variables are detected on deploy.
102+
* [Use blocks][date-block] when declaring date and time attributes in FactoryGirl factories.
103+
* Use `touch: true` when declaring `belongs_to` relationships.
100104

105+
[date-block]: /best-practices/samples/ruby.rb#L10
106+
[fkey]: http://robots.thoughtbot.com/referential-integrity-with-foreign-keys
101107
[`.ruby-version`]: https://gist.github.com/fnichol/1912050
102108
[redirects]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30
103109
[Spring binstubs]: https://github.com/sstephenson/rbenv/wiki/Understanding-binstubs
104110
[prevent tampering]: http://blog.bigbinary.com/2013/03/19/cookies-on-rails.html
111+
[class constant in association]: https://github.com/thoughtbot/guides/blob/master/style/rails/sample.rb
105112

106113
Testing
107114
-------
108115

109116
* Avoid `any_instance` in rspec-mocks and mocha. Prefer [dependency injection].
110-
* Avoid `its`, `let`, `let!`, `specify`, and `before` in RSpec.
117+
* Avoid `its`, `specify`, and `before` in RSpec.
118+
* Avoid `let` (or `let!`) in RSpec. Prefer extracting helper methods,
119+
but do not re-implement the functionality of `let`. [Example][avoid-let].
111120
* Avoid using `subject` explicitly *inside of an* RSpec `it` block.
112121
[Example][subject-example].
113122
* Avoid using instance variables in tests.
@@ -125,7 +134,8 @@ Testing
125134
* Use non-[SUT] methods in expectations when possible.
126135

127136
[dependency injection]: http://en.wikipedia.org/wiki/Dependency_injection
128-
[explicit subject example]: /style/samples/testing.rb#17
137+
[subject-example]: ../style/testing/unit_test_spec.rb
138+
[avoid-let]: ../style/testing/avoid_let_spec.rb
129139
[`Delayed::Job` matcher]: https://gist.github.com/3186463
130140
[stubs and spies]: http://robots.thoughtbot.com/post/159805295/spy-vs-spy
131141
[assertions about state]: https://speakerdeck.com/skmetz/magic-tricks-of-testing-railsconf?slide=51
@@ -155,6 +165,9 @@ Postgres
155165
* Consider a [partial index] for queries on booleans.
156166
* Constrain most columns as [`NOT NULL`].
157167
* [Index foreign keys].
168+
* Use an `ORDER BY` clause on queries where the results will be displayed to a
169+
user, as queries without one may return results in a changing, arbitrary
170+
order.
158171

159172
[`NOT NULL`]: http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#AEN2444
160173
[combines multiple indexes]: http://www.postgresql.org/docs/9.1/static/indexes-bitmap-scans.html
@@ -173,17 +186,28 @@ Email
173186

174187
* Use [SendGrid] or [Amazon SES] to deliver email in staging and production
175188
environments.
176-
* Use a tool like [MailView] to look at each created or updated mailer view
177-
before merging.
189+
* Use a tool like [ActionMailer Preview] to look at each created or updated mailer view
190+
before merging. Use [MailView] gem unless using Rails version 4.1.0 or later.
178191

179192
[Amazon SES]: http://robots.thoughtbot.com/post/3105121049/delivering-email-with-amazon-ses-in-a-rails-3-app
180193
[SendGrid]: https://devcenter.heroku.com/articles/sendgrid
181194
[MailView]: https://github.com/37signals/mail_view
195+
[ActionMailer Preview]: http://api.rubyonrails.org/v4.1.0/classes/ActionMailer/Base.html#class-ActionMailer::Base-label-Previewing+emails
196+
197+
Web
198+
---
199+
200+
* Avoid a Flash of Unstyled Text, even when no cache is available.
201+
* Avoid rendering delays caused by synchronous loading.
202+
* Use https instead of http when linking to assets.
182203

183204
JavaScript
184205
----------
206+
* Use the latest stable JavaScript syntax with a transpiler, such as [babel].
207+
* Include a `to_param` or `href` attribute when serializing ActiveRecord models,
208+
and use that when constructing URLs client side, rather than the ID.
185209

186-
* Use CoffeeScript.
210+
[babel]: http://babeljs.io/
187211

188212
HTML
189213
----
@@ -196,6 +220,10 @@ CSS
196220
---
197221

198222
* Use Sass.
223+
* Use [Autoprefixer][autoprefixer] to generate vendor prefixes based on the
224+
project-specific browser support that is needed.
225+
226+
[autoprefixer]: https://github.com/postcss/autoprefixer
199227

200228
Sass
201229
----
@@ -209,8 +237,7 @@ Sass
209237
Browsers
210238
--------
211239

212-
* Don't support clients without Javascript.
213-
* Don't support IE6 or IE7.
240+
* Avoid supporting versions of Internet Explorer before IE10.
214241

215242
Objective-C
216243
-----------
@@ -291,6 +318,20 @@ Ember
291318
* Don't use jQuery outside of views and components.
292319
* Prefer to use predefined `Ember.computed.*` functions when possible.
293320
* Use `href="#"` for links that have an action.
321+
* Prefer dependency injection through `Ember.inject` over initializers, globals
322+
on window, or namespaces. ([sample][inject])
323+
* Prefer sub-routes over maintaining state.
324+
* Prefer explicit setting of boolean properties over `toggleProperty`.
325+
* Prefer testing your application with [QUnit][ember-test-guides].
326+
327+
[ember-test-guides]: https://guides.emberjs.com/v2.2.0/testing/
328+
329+
Testing
330+
331+
* Prefer `findWithAssert` over `find` when fetching an element you expect to
332+
exist
333+
334+
[inject]: samples/ember.js#L1-L11
294335

295336
Angular
296337
-------
@@ -307,3 +348,18 @@ Angular
307348
[annotations]: http://robots.thoughtbot.com/avoid-angularjs-dependency-annotation-with-rails
308349
[ngannotate]: https://github.com/kikonen/ngannotate-rails
309350
[angular-translate]: https://github.com/angular-translate/angular-translate/wiki/Getting-Started#using-translate-directive
351+
352+
Ruby JSON APIs
353+
--------------
354+
355+
* Review the recommended practices outlined in Heroku's [HTTP API Design Guide]
356+
before designing a new API.
357+
* Use a fast JSON parser, e.g. [`oj`][oj]
358+
* Write integration tests for your API endpoints. When the primary consumer of
359+
the API is a JavaScript client maintained within the same code base as the
360+
provider of the API, write [feature specs]. Otherwise write [request specs].
361+
362+
[HTTP API Design Guide]: https://github.com/interagent/http-api-design
363+
[oj]: https://github.com/ohler55/oj
364+
[feature specs]: https://www.relishapp.com/rspec/rspec-rails/docs/feature-specs/feature-spec
365+
[request specs]: https://www.relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec

best-practices/samples/ember.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Ember from 'ember';
2+
3+
const { inject } = Ember;
4+
5+
export default Ember.Controller({
6+
applicationController: inject.controller('application'),
7+
index: inject.controller(),
8+
9+
toastService: inject.service('toast'),
10+
store: inject.service(),
11+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!-- Use toParam when constructing URLs, not ID -->
2+
<!-- Good -->
3+
<a href="/posts/{{ post.toParam }}">
4+
<!-- Bad -->
5+
<a href="/posts/{{ post.id }}">

best-practices/samples/ruby.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Include an href or to_param attribute when serializing models
2+
class PostSerializer < ActiveModel::Serializer
3+
attributes :id, :content, :to_param
4+
5+
delegate :to_param, to: :object
6+
end
7+
8+
FactoryGirl.define do
9+
factory :event do
10+
start_on { 1.week.from_now }
11+
end
12+
end

code-review/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ Having Your Code Reviewed
4646
Reviewing Code
4747
--------------
4848

49-
Understand why the code is necessary (bug, user experience, refactoring). Then:
49+
Understand why the change is necessary (fixes a bug, improves the user
50+
experience, refactors the existing code). Then:
5051

5152
* Communicate which ideas you feel strongly about and those you don't.
5253
* Identify ways to simplify the code while still solving the problem.

how-to/README.rst

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
How do I ...
2+
============
3+
4+
.. contents::
5+
6+
... start a new Rails app?
7+
--------------------------
8+
9+
Use suspenders_:
10+
11+
.. code:: sh
12+
13+
$ gem install suspenders
14+
$ suspenders the-name-of-your-project-here
15+
$ cd the-name-of-your-project-here/
16+
$ bin/setup
17+
$ rake
18+
19+
.. _suspenders: https://github.com/thoughtbot/suspenders
20+
21+
... feature-test a Rails app's Javascript?
22+
------------------------------------------
23+
24+
Use capybara-webkit_. In your ``Gemfile``:
25+
26+
.. code:: ruby
27+
28+
gem "capybara-webkit"
29+
30+
In ``spec/support/capybara_webkit.rb`` (for Rspec):
31+
32+
.. code:: ruby
33+
34+
Capybara.javascript_driver = :webkit
35+
36+
Capybara::Webkit.configure do |config|
37+
config.block_unknown_urls
38+
end
39+
40+
When writing a spec, you must set the ``:js`` flag for that test to make use of
41+
capybara-webkit. For example, in ``spec/features/user_signs_in_spec.rb``:
42+
43+
.. code:: ruby
44+
45+
feature "Authentication", :js do
46+
scenario "A user signing in" do
47+
create(:user, email: "[email protected]", password: "sekrit")
48+
49+
sign_in_as email: "[email protected]", password: "sekrit"
50+
51+
expect(page).to have_text("Welcome!")
52+
end
53+
end
54+
55+
.. _capybara-webkit: https://github.com/thoughtbot/capybara-webkit

protocol/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Guides for getting things done.
55

66
* [Communication](/protocol/communication)
77
* [Git](/protocol/git)
8-
* [Rails](/protocol/rails)
98
* [iOS](/protocol/ios)
109
* [Open Source](/protocol/open-source)
10+
* [Product Review](/protocol/product-review)
11+
* [Rails](/protocol/rails)

protocol/git/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ Create a local feature branch based off master.
2424
git pull
2525
git checkout -b <branch-name>
2626

27-
Prefix the branch name with your initials.
28-
2927
Rebase frequently to incorporate upstream changes.
3028

3129
git fetch origin
@@ -49,8 +47,9 @@ Write a [good commit message]. Example format:
4947

5048
http://project.management-system.com/ticket/123
5149

52-
If you've created more than one commit, use a rebase to squash them into
53-
cohesive commits with good messages:
50+
If you've created more than one commit,
51+
[use `git rebase` interactively](https://help.github.com/articles/about-git-rebase/)
52+
to squash them into cohesive commits with good messages:
5453

5554
git rebase -i origin/master
5655

@@ -100,7 +99,7 @@ Force push your branch. This allows GitHub to automatically close your pull
10099
request and mark it as merged when your commit(s) are pushed to master. It also
101100
makes it possible to [find the pull request] that brought in your changes.
102101

103-
git push --force origin <branch-name>
102+
git push --force-with-lease origin <branch-name>
104103

105104
View a list of new commits. View changed files. Merge branch into master.
106105

0 commit comments

Comments
 (0)