Ruby and Rails with Style
Based on Bozidar Batsov's "Ruby style guide"
Curly braces
# good - space after { and before }
{ one: 1, two: 2 }
# good - no space after { and before }
{one: 1, two: 2}
Use spaces around the = operator when assigning default values to method parameters
# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
# do something...
end
# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
# do something...
end
Multi-line method chaining
Two options
Option one
# bad - need to consult first line to
# understand second line
one.two.three.
four
# good - it's immediately clear what's
# going on the second line
one.two.three
.four
Option two
# bad - need to read ahead to the second line
# to know that the chain continues
one.two.three
.four
# good - it's immediately clear that the
# expression continues beyond the first line
one.two.three.
four
Use :: only to reference constants(this includes classes and modules) and constructors (likeArray() or Nokogiri::HTML()). Do not use :: for regular method invocation.
# bad
SomeClass::some_method
some_object::some_method
# good
SomeClass.some_method
some_object.some_method
SomeModule::SomeClass::SOME_CONST
SomeModule::SomeClass()
Use def with parentheses when there are parameters. Omit the parentheses when the method doesn't accept any parameters.
# bad
def some_method()
# body omitted
end
# good
def some_method
# body omitted
end
# bad
def some_method_with_parameters param1, param2
# body omitted
end
# good
def some_method_with_parameters(param1, param2)
# body omitted
end
Leverage the fact that if and case are expressions which return a result.
# bad
if condition
result = x
else
result = y
end
# good
result =
if condition
x
else
y
end
Logical operators
- Use ! instead of not
- The and and or keywords are banned. It's just not worth it. Always use && and || instead.
Favor modifier if/unless usage when you have a single-line body. Another good alternative is the usage of control flow &&/||
# bad
if some_condition
do_something
end
# good
do_something if some_condition
# another good option
some_condition && do_something
Do not use unless with else. Rewrite these with the positive case first.
# bad
unless success?
puts 'failure'
else
puts 'success'
end
# good
if success?
puts 'success'
else
puts 'failure'
end
Omit the outer braces around an implicit options hash.
# bad
user.set({ name: 'John', age: 45, permissions: { read: true } })
# good
user.set(name: 'John', age: 45, permissions: { read: true })
Omit parentheses for method calls with no arguments.
# bad
Kernel.exit!()
2.even?()
fork()
'test'.upcase()
# good
Kernel.exit!
2.even?
fork
'test'.upcase
Do not omit otherwise, especially when method returns value
# bad
array.delete hash.fetch :foo
# good
array.delete(hash.fetch(:foo))
# bad
result = calculate array, start_point, steps
# good
result = calculate(array, start_point, steps)
Don't use the return value of = (an assignment) in conditional expressions unless the assignment is wrapped in parentheses.
Subtitle
# bad (+ a warning)
if v = array.grep(/foo/)
do_something(v)
...
end
# good (MRI would still complain, but RuboCop won't)
if (v = array.grep(/foo/))
do_something(v)
...
end
# good
v = array.grep(/foo/)
if v
do_something(v)
...
end
Use a consistent structure in your class definitions.
- includes and extends
- inner classes
- constants
- attribute macros
- other macros
- public class methods
- public instance methods
- protected methods
- private methods
class Person
# extend and include go first
extend SomeModule
include AnotherModule
# inner classes
CustomErrorKlass = Class.new(StandardError)
# constants are next
SOME_CONSTANT = 20
# afterwards we have attribute macros
attr_reader :name
# followed by other macros (if any)
validates :name
# public class methods are next in line
def self.some_method
end
# followed by public instance methods
def some_method
end
# protected and private methods are grouped near the end
protected
def some_protected_method
end
private
def some_private_method
end
end
Rails, in short
Each controller action should (ideally) invoke only one method other than an initial find or new.
Share no more than two instance variables between a controller and a view.
Always use the new "sexy" validations.
# bad
validates_presence_of :email
# good
validates :email, presence: true
Enforce foreign-key constraints.
Don't use model classes in migrations. The model classes are constantly evolving and at some point in the future migrations that used to work might stop, because of changes in the models used.
Miscellanea
Avoid needless metaprogramming.
Avoid methods longer than 10 LOC (lines of code). Ideally, most methods will be shorter than 5 LOC. Empty lines do not contribute to the relevant LOC.
Use common sense.
Ruby and Rails with Style
By katafrakt
Ruby and Rails with Style
- 1,202