Skip to content

Latest commit

 

History

History
523 lines (452 loc) · 12.5 KB

style_guide.md

File metadata and controls

523 lines (452 loc) · 12.5 KB

Each bullet links to an example of both the incorrect and correct pattern(s) for that particlar rule.

General

Prefer double quotes for strings.

  # bad
  'Kaladin Stormblessed'

  # good
  "Kaladin Stormblessed"

⬆ Back to Top

Use spaces around curly braces

  # bad
  {name: "Kelsier", title: "Survivor of Hathsin"}

  # good
  { name: "Kelsier", title: "Survivor of Hathsin" }

⬆ Back to Top

Don't use spaces around square brackets

  # bad
  [ "Frodo", "Gandalf", "Aragorn", "Legolas", "Gimli", "Sam", "Merry", "Pippin" ]

  # good
  ["Frodo", "Gandalf", "Aragorn", "Legolas", "Gimli", "Sam", "Merry", "Pippin"]

⬆ Back to Top

Use a trailing comma after the last item in a multi-line list.

  # bad
  elephants = [
    "Dumbo",
    "Jumbo",
    "Bumbo",
    "Wumbo"
  ]

  # good
  elephants = [
    "Dumbo",
    "Jumbo",
    "Bumbo",
    "Wumbo",
  ]

⬆ Back to Top

Avoid explicit return statements.

  # bad
  def sum(operand_1, operand_2)
    return operand_1 + operand_2
  end

  # good
  def sum(operand_1, operand_2)
    operand_1 + operand_2
  end

⬆ Back to Top

Avoid multiple assignments per line.

  # bad
  def sum(operand_1, operand_2)
    x, y = operand_1, operand_2
    x + y
  end

  # good
  def sum(operand_1, operand_2)
    x = operand_1
    y = operand_2
    x + y
  end

⬆ Back to Top

Prefer && and || over AND and OR.

  # bad
  def valid_pizza?
    heavy_pizza? or (light_pizza? and big_pizza?)
  end

  # good
  def valid_pizza?
    heavy_pizza? || (light_pizza? && big_pizza?)
  end

⬆ Back to Top

Prefer ! over not.

  # bad
  def valid_pizza?
    not small_pizza?
  end

  # good
  def valid_pizza?
    !small_pizza?
  end

⬆ Back to Top

Use %{} for single-line strings containing double-quotes that require interpolation.

  # bad
  def insert_annoying_thing_into_string
    thing = "annoying"
    'i am an "' + thing + '" string'
  end

  # good
  def insert_annoying_thing_into_string
    thing = "annoying"
    %{i am an "#{thing}" string}
  end

⬆ Back to Top

Avoid using semicolons.

  # bad
  def sum(operand_1, operand_2)
    operand_1 + operand_2;
  end

  # good
  def sum(operand_1, operand_2)
    operand_1 + operand_2
  end

⬆ Back to Top

Avoid organizational comments.

  # bad
  class Dog
    # associations
    belongs_to :user
    belongs_to :home
    has_many :favorite_foods

    # validations
    validates :name, presence: true
    validates :color, presence: true
    validates :breed, presence: true
  end

  # good
  class Dog
    belongs_to :user
    belongs_to :home
    has_many :favorite_foods

    validates :name, presence: true
    validates :color, presence: true
    validates :breed, presence: true
  end

⬆ Back to Top

Use CamelCase for classes and modules, snake_case for variables, methods, and file names, SCREAMING_SNAKE_CASE for constants.

  # bad
  # app/models/LoudCamelSnakes.rb
  class loudCamelSnakes
    maximum_camelsnake_capacity = 450

    def SneakyCamelSnake
    end
  end

  # good
  # app/models/loud_camel_snakes.rb
  class LoudCamelSnakes
    MAXIMUM_CAMELSNAKE_CAPACITY = 450

    def sneaky_camel_snake
    end
  end

⬆ Back to Top

Conditionals

Avoid lines that end with complex conditionals.

  # bad
  def sum(operand_1, operand_2)
    operand_1 + operand_2 if operand_is_valid(operand_1) && operand_is_valid(operand_2)
  end

  # good
  def sum(operand_1, operand_2)
    if operand_is_valid(operand_1) && operand_is_valid(operand_2)
      operand_1 + operand_2
    end
  end

  # also good
  def sum(operand_1, operand_2)
    operand_1 + operand_2 if valid_operands?
  end

⬆ Back to Top

Avoid ternary operators.

  # bad
  def sum(operand_1, operand_2)
    valid_operands? ? operand_1 + operand_2 : raise InvalidOperandError
  end

  # good
  def sum(operand_1, operand_2)
    if valid_operands?
      operand_1 + operand_2
    else
      raise InvalidOperandError
    end
  end

⬆ Back to Top

Prefer if over unless.

  • use unless for a single negation; use if otherwise.
  # bad
  def perform
    if !pizza.expired?
      eat_pizza
    end
  end

  # also bad
  def perform
    unless pizza.expired? || !pizza.tasty?
      eat_pizza
    end
  end

  # good
  def perform
    unless pizza.expired?
      eat_pizza
    end
  end

  # also good
  def perform
    if pizza.tasty? && !pizza.expired?
      eat_pizza
    end
  end

⬆ Back to Top

Blocks

Prefer &:method_name for simple method calls.

  # bad
  def delicious_pizza?
    toppings.detect{ |topping| topping.delicious }
  end

  # good
  def delicious_pizza?
    toppings.detect(&:delicious)
  end

⬆ Back to Top

Use {...} for single-line blocks. Use do..end for multi-line blocks.

  # bad
  def choose_best_vacations(places)
    places.select { |place|
      place.super_fun?
    }
  end

  # also bad
  def choose_best_vacations(places)
    places.select do |place| place.super_fun? end
  end

  # good
  def choose_best_vacations(places)
    places.select do |place|
      place.super_fun?
    end
  end

  # also good
  def choose_best_vacations(places)
    places.select { |place| place.super_fun? }
  end

⬆ Back to Top

Prefer detect, select, map, and reduce for iteration.

  # bad
  def find_elephants(animals)
    elephants = []
    animals.each do |animal|
      if animal.species == "Elephant"
        elephants << animal
      end
    end
  end

  # good
  def find_elephants(animals)
    animals.select do |animal|
      animal.species == "Elephant"
    end
  end

⬆ Back to Top

Classes & Methods

Use ? suffix for predicate methods, and avoid prefixing auxiliary verbs.

  # bad
  def is_big
    dinosaur.size == "big"
  end

  # also bad
  def is_big?
    dinosaur.size == "big"
  end

  # good
  def big?
    dinosaur.size == "big"
  end

⬆ Back to Top

Use def with parentheses when there are arguments.

  # bad
  def find_elephants animals
    animals.select do |animal|
      animal.species == "Elephant"
    end
  end

  # good
  def find_elephants(animals)
    animals.select do |animal|
      animal.species == "Elephant"
    end
  end

⬆ Back to Top

Don't use spaces after required keyword arguments.

  # bad
  def sum(operand_1: , operand_2: , operand_3:)
    operand_1 + operand_2 + operand_3
  end

  # good
  def sum(operand_1:, operand_2:, operand_3:)
    operand_1 + operand_2 + operand_3
  end

⬆ Back to Top

Avoid bang method names

  • Bang (!) usually denotes a "dangerous" method, meaning that it will modify the object it's called on.
  # bad
  class Bus
    def number_of_wheels!(bus_params)
      self.number_of_wheels = bus_params[:number_of_wheels]
      self.save
    end
  end

  # good
  class Bus
    def update_number_of_wheels(bus_params)
      self.number_of_wheels = bus_params[:number_of_wheels]
      self.save
    end
  end

  # also good
  class Bus
    def update_number_of_wheels!(bus_params)
      self.number_of_wheels = bus_params[:number_of_wheels]
      self.save!
    end
  end

⬆ Back to Top

Don't use self explicitly except for class methods and assignments.

  # bad
  class Bus
    def pounds_per_meter
      self.weight / self.height
    end
  end

  # good
  class Bus
    def pounds_per_meter
      weight / height
    end
  end

  # also good
  class Bus
    def self.heavy_buses
      Bus.where(weight: 50000)
    end
  end

⬆ Back to Top

Prefer shorthand class and module definitions.

  # bad
  class Automobile
    class Bus
      def pounds_per_meter
        weight / height
      end
    end
  end

  # good
  class Bus::Automobile
    def pounds_per_meter
      weight / height
    end
  end

⬆ Back to Top

Order class methods above instance methods.

  # bad
  class Rollercoaster
    def rider_capacity
      number_of_cars * seats_per_car
    end

    def self.perfect_rollercoasters
      Rollercoaster.where(score: 10)
    end

    def seats_per_car
      car.number_of_seats
    end
  end

  # good
  class Rollercoaster
    def self.perfect_rollercoasters
      Rollercoaster.where(score: 10)
    end

    def seats_per_car
      car.number_of_seats
    end

    def rider_capacity
      number_of_cars * seats_per_car
    end
  end

⬆ Back to Top