Automatic enforcement with Rubocop
To help us enforce similar style between project everyone should use rubocop from now on
https://gist.github.com/Ostrzy/c3debe7a47ccdf920591
Just save this to
~/.rubocop.yml
Or add .rubocop.yml
straight to project root folder( then it can be customized a little )
There are several plugins to editors that help you lint/autocorrect code with rubocop:
- ATOM
- Linter Rubocop
- Rubocop Auto Correct
- SUBLIME
- Sublime Linter Rubocop
! Remember that you can use (bundle exec) rubocop -a
which automatically fixes some cops violations.
Adding rubocop to circleCi is best used with pre test commit hook in circle.yml
file in project root folder.
test:
pre:
- bundle exec rubocop
-
Consider using
Hash#fetch
instead ofHash#[]
.The first one throws exception where it fails to read a key. In the second case we usually get
undefined method ... for nil:NilClass
somewhere else in the code. The first one is better for debug. -
Use of new ruby hash syntax for new projects.
Use old syntax only when necessary, for example to put non-symbol as a key.
-
Always use double-quoted strings.
-
Avoid rescuing StandardError and Exception
They should never be rescued, if they are raised, we should get notified by getsentry and fix them.
-
Use semantic versions for all gems in Gemfile before pushing to production.
-
Always define dependent on AR relations. It is often a case that definition of
dependent
wasn't added because someone just forget about that. We should always do:has_many :objects, dependent: :destroy # when the object is destroyed, destroy will be called on its associated objects has_many :object, dependent: :delete_all # when the object is destroyed, all its associated objects will be deleted directly from the database without calling their destroy method (for has_one use :delete) has_many :objects, dependent: :nullify # causes the foreign key to be set to NULL. Callbacks are not executed has_many :objects, dependent: :restrict_with_exception # causes an exception to be raised if there is an associated record has_many :objects, dependent: :restrict_with_error # causes an error to be added to the owner if there is an associated object
You shouldn't need to use
dependent
onbelongs_to
-
Try to avoid calling self explicitly on reads
Prefer
def pay_with_balance? has_payment? && balance > 0 && payment_applied > 0 end
over
def pay_with_balance? self.has_payment? && self.balance > 0 && self.payment_applied > 0 end
-
Don't overuse one letter variables unless it is very short block, repeating variable or exception.
Acceptable:
[1,2,3].map{ |e| e + 1 }
rescue Exception => e
# ...
end
user.tap do |u|
u.uid = user_hash['uid']
u.email = user_hash['email']
u.name = user_hash['name']
u.save!
end
Not acceptable:
if a = variant.address
[a.country_code, a.state || a.city].join("-")
end
array.inject({}) do |h, e|
h[foo] = e.bar
h
end
def process_text(s)
# ...
end
- Use trailing commas in multiline hashes and multiline arrays. If you'd like to add an element you won't left your comma on the previous line. It helps to keep VCS history clean.
// Bad // Good // Bad // Good
arr = [ arr = [ hsh = { hsh = {
'foo', 'foo', foo: 'foz', foo: 'foz',
'bar' 'bar', bar: 'baz' bar: 'baz',
] ] } }
- Do NOT indent methods below
private
/protected
keywords
- use a new expectation syntax when using RSpec (see issue):
it { expect(something).to be_valid }
- Use Node.js instead of therubyracer for execjs runtime