Style

Limit lines to 80 characters. Never leave trailing whitespace. End each file with a newline. Avoid more than three levels of block nesting.

Indentation

Use two spaces per level of indentation. No hard tabs.
  def some_method
    do_something
  end
For case statements, 'when' should align with 'case'.
case
when thing == 'thing'
  do_something
when thing == 'other thing'
  do_something_else
else
  do_something_completely_different
end
When assigning with a case statement, everything should be indented and aligned.
thing =
  case foo
  when foo then 'bar'
  when bar then 'foo'
  else 'baz'
  end

thing =
  if foo
    'bar'
  else
    'baz'
  end

Line format

Use new lines per expressions or statements, do not use ;.

bad

puts 'foo'; puts 'bar'

good

puts 'foo' puts 'bar'
Use an empty line between methods.
def some_method
  do_something
end

def some_method
  do_something
end
Use an empty line to break methods into logical sections.
def some_method
  data = initialize

  data.do_something

  data.result
end
Use lines to separate long list of parameters.

bad

def send_mail(source) Mailer.deliver(to: 'email@example.com', from: 'another@example.com', subject: 'Some title', body: "foo bar baz") end

good

def send_mail(source) Mailer.deliver( to: 'email@example.com', from: 'another@example.com', subject: 'Some title', body: "foo bar baz" ) end
Align array elements over multiple lines.

bad

menu_item = ['Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo']

good

menu_item = [ 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo', 'Foo' ]
Use single line format for empty class definitions.

bad

class Suprise < StandardError end

good

class Suprise < StandardError; end

good

Suprise = Class.new(StandardError)
Use multi line format for methods.

bad

def some_method; do_something; end

good

def some_method do_something end

Whitespace

Use white space to make your code more readable.
thing = 1 + 4 - 10
a, b, c, d
[1, 2, 3].each { | k, v | puts v if k == 10 }
"interpolate #{ this }"
There are a few exceptions where you cannot use whitespace as it will cause an error.
some_method(argument)
["some", "array"].first
!something

Syntax

Use :: only to reference constants and constructors, not for regular method invocation.
FooClass.some_method
foo_object.some_method
BareModule::FooClass::CONSTANT
BarModule::FooClass
Only use parentheses on methods that accept parameters.
def some_method
  body
end

def some_method(arg1, arg2)
  body
end
Use the each method in favour of the for method.

bad

for element in array do puts element end

good

array.each { |element| puts element }
When it is readable and not multiline, favour the ternary opertor over an if statment.

bad

thing = if foo == bar then do_something else do_something_else end

good

thing = foo == bar ? do_something : do_something_else
Unless it is a single conditional.
do_something if foo == bar
Do not use !! to check if a value is nil, instead use .nil?.

bad

if !!foo

good

unless foo.nil?
Use operators, not keywords.
and   

bad

&&

good

or

bad

||

good

not

bad

!

good

Don't use double negatives.
if !condition     

bad

unless condition

good

while !condition

bad

until condition

good

Omit the outer braces around an implicit options hash.

bad

user.set({ name: 'admin', authorization: { read: true, write: true } })

good

user.set(name: 'admin', authorization: { read: true, write: true })
Use { } for single-line blocks.

bad

things.each do |thing| puts thing end

good

things.each { |thing| puts thing }
Avoid return where not required.

bad

def some_method return something end

good

def some_method something end
Use shorthand self assignment operators whenever applicable.

bad

x = x + y is the same as x += y x = x * y is the same as x *= y x = x**y is the same as x **= y x = x / y is the same as x /= y x = x && y is the same as x &&= y
Use ||= when you want to initialise variables only if they're not already initialised.
foo ||= 'bar'
Use &&= to preprocess variables that may or may not exist.

bad

if something something = something.downcase end

good

something &&= something.downcase
Use the new lambda literal syntax for single line body blocks.
l = ->(x, y) { x = y }
Use the lambda method for multi-line blocks.
l = lambda do |x, y|
  foo = y
  bar = x
end
Prefer proc over Proc.new.

bad

p = Proc.new { |n| puts n } p.()

good

p = proc { |n| puts n } p.call()
Favour the use of predicate methods to explicit comparisons.
x.even?
x.odd?
x.nil?
x.zero?

Classes

Avoid self where not required. It is only required when calling a self write accessor. Use a consistent structured order in classes. 1. extend and include 2. constants 3. attribute macros 4. other macros 5. public class methods 6. public instance methods 7. protected methods 8. private methods Prefer modules to classes with only class methods. Classes should be used only when it makes sense to create instances out of them.

bad

class SomeClass def self.some_method do_something end def self.some_other_method end end

good

module SomeClass def some_method do_something end def some_other_method end end
Use attr functions to define accessors.
class Foo
  attr_reader :bar, :baz
end
Avoid the usage of class variables. It will cause unexpected results with inheritance. Class instance variables should usually be preferred over class variables. Assign proper visibility levels to methods (private, protected) in accordance with their intended usage.
class FooClass
  def public_method
    do_something
  end

  private

  def private_method
    do_something
  end
end
Use def self.method to define singleton methods.
class FooClass
  def self.some_method
    do_something
  end
end
Or if you have multiple.
class FooClass

  module ClassMethods
    def some_method
      do_something
    end

    def other_method
      do_something
    end
  end

end

Methods

Avoid hashes as optional parameters. Does the method do too much? Object initialisers are exceptions for this rule. Ideally, most methods will be shorter than 5 lines. Empty lines do not contribute to this.

Arrays and Hashes

Prefer literal array and hash creation notation.
arr = []
hash = {}
Prefer %w for strings, or %i for symbols to the literal array syntax.
things = %w(draft open closed)
things = %i(draft open closed)
Prefer symbols instead of strings as hash keys.
hash = { foo: 1, bar: 2, baz: 3 }

Strings

Use string interpolation rather than string concatenation.

bad

foo = bar.baz + ', ' + bar.qux

good

foo = "#{ bar.baz }, #{ bar.qux }"
Prefer double-quotes unless your string literal contains " or escape characters you want to suppress.
foo = "Bar"

Exceptions

Don't use exceptions to control flow.

bad

begin foo / bar rescue ZeroDivisionError "Can't do this" end

good

if foo.zero? "Can't do this" else foo / bar end
Use raise only when catching an exception and re-raising it.
begin
  fail 'BAD'
rescue => error
  raise if error.message != 'BAD'
end
Supply an exception class and a message as two separate arguments.

bad

fail SomeException.new('message')

good

fail SomeException, 'message'
Use implicit begin blocks where possible.

bad

def foo begin

main logic goes here

rescue

failure handling goes here

end end

good

def foo

main logic goes here

rescue

failure handling goes here

end

Naming

Name identifiers in English. Use snake_case for naming files and directories. Use snake_case for symbols, methods and variables and constants.
:some_symbol

def some_method
  ...
end

SOME_CONSTANT = nil
Use CamelCase for classes and modules.
class SomeClass
  ...
end
Methods that return a boolean value should end in a question mark.
class boolean_method?
  ...
end
Methods which overwrite a value should end with a bang if there is a non bang version available.
class Foo
  def bar!
  end

  def bar
  end
end

Commenting

Keep comments up to date.

Don't use block comments. They cannot be preceded by whitespace and are not as easy to spot as regular comments.

bad

=begin comment line another comment line =end

good

comment line

another comment line

Good code is its own best documentation. As you’re about to add a comment, ask yourself, “How can I improve the code so that this comment isn’t needed?” Improve the code and then document it to make it even clearer.
— Steve McConnell