Skip to content
redsummernight edited this page Jul 2, 2021 · 7 revisions

Everyone should adhere to the same standards, and any new code should meet the standards before being merged. Even if one element or another is mildly annoying to some coders, overall the benefit of having the same standard across the project outweighs that.

A lot of these standards are enforced by Rails and its automatic generation, which is helpful. Hound runs on all pull requests and leaves comments about style violations in .rb files; view files will be checked manually by one of our developers.

Table of Contents

General code formatting

We follow whatever is the most popular convention listed in the Ruby Styleguide.

  • 2 space indents
  • Double quotes for strings
  • Generally minimize parentheses and brackets
    • No spaces inside parentheses or brackets, e.g. [a, b, c] and (2 + 2)
  • CONSTANTS_USE_UPPER_CASE
  • ClassesUsePascalCase
    • Note: Acronyms should be kept capitalized: MyXMLClass not MyXmlClass
  • methods, local_variables, @instance_variables, and @@class_variables all use_lower_case_and_underscores
  • Use curly braces for one-line blocks and do...end for multi-line blocks.
    • Spaces before and inside curly braces, e.g. things.each { |t| t.name }
  • If you have any "complicated" arguments to a function, put the parameter list inside parentheses. Stick the opening parenthesis of the parameter list up tight against the name of the method, i.e., Math.sqrt(2 + 2) and not Math.sqrt (2 + 2).
Refer to the Automated Testing page for test-specific standards.

Previewing Hound comments

You can check for style violations locally, without waiting until you have a pull request for Hound to look at.

First, you need to install the linters. In your project directory, run:

BUNDLE_GEMFILE=Gemfile.linters bundle install

Then you can run RuboCop on any .rb file, e.g.:

BUNDLE_GEMFILE=Gemfile.linters bundle exec rubocop app/controllers/works_controller.rb

where .rubocop.yml is the same settings Hound uses. Don't worry if you see a lot of violations: the above RuboCop command checks the whole file, while Hound only looks at the lines you change. You can (and should!) ignore anything that isn't related to the lines you've changed.

You can also run ERB Lint on any template (.erb) file:

BUNDLE_GEMFILE=Gemfile.linters bundle exec erblint .

where .erb-lint.yml is the same settings Hound uses.

OTW-Specific standards

Front end

Refer to Front End Coding Standards for help formatting CSS and HTML.

Translations

Any string in a view should have the translation function tacked on. That is, instead of:

<h1>Title Of This Page</h1>
<p>Here is your name, <%= user.username -%>.</p>

You should instead have:

<h1><%= ts("Title Of This Page") %></h1>
<p><%= ts("Here is your name, %{name}.", name: user.username) %></p>

The %{} operators will cause these strings to magically get added to the translation interface, and then as soon as a translation is added, the translation will automatically appear when the user has the appropriate locale set!

Testing

Every piece of functionality should have matching tests in Cucumber or RSpec.

Before you fix a bug, create a test to catch that bug, then fix it and check the test now passes.

Run relevant tests frequently: the sooner you discover you broke something, the easier it is to fix it.

Commenting

Every method should have at least one short comment directly above the function definition. This comment should be edited if the function is changed to reflect that change. For example,

# This cool comment will automatically turn into 
# HTML documentation (when rake doc:app is run).
def awesome_method
  "Look how awesome I am"
end

Database standards

See also the Migrations page.

  • All database access should go through Rails and the ActiveRecord models it uses, unless raw SQL is absolutely required.
  • A Rails ActiveRecord model corresponds to a table in the database. Every model name should be a singular noun (e.g. "User" or "Work"), and the corresponding table in the database should be a plural noun (e.g. "users" or "works"). Use the automatic Rails generators and they will handle this for you!
  • We will generally use the term "model" here since you'll be working primarily in Rails. You only need to think about tables if you actually have to manually do work on the database through MySQL.
  • Tables which exist solely to join two other tables together are named for the concept or for both tables (an underscore separates words, only the last word should be plural). Mostly you will not need to create these kinds of tables yourself because Rails hides them from you invisibly using the has_many, has_one, and belongs_to types of relationships.
  • Every table will have a numeric column named id as its primary key.
  • Joins between tables should always use this id key.
  • If you use another table's primary key as a key in a second model, that column should be named [descriptive word]_[first model nonplural]_id For example, if we had a users table and a stories table, author_user_id in the stories model would be an author field, which is filled with the id field from the users model. (The descriptive word is optional but encouraged if any confusion is possible.) This key should always be defined in the database as a foreign key.
  • If a length limitation is placed on a text field, that length should be defined on the corresponding model's column in the database.