Skip to content
Bilka edited this page May 21, 2024 · 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. Reviewdog runs on all pull requests and leaves comments about style violations in .rb and html.erb files.

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 Reviewdog comments

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

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

bundle exec rubocop app/controllers/works_controller.rb

where .rubocop.yml is the same settings Reviewdog uses. Don't worry if you see a lot of violations: the above RuboCop command checks the whole file, while Reviewdog 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, e.g.:

bundle exec erblint app/views/works/show.html.erb

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

OTW-Specific standards

Front end

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

Translations

Refer to the Internationalization (i18n) Standards.

Any string in a view should use the translation function. That is, instead of this in a view:

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

You should instead have:

<h1><%= t(".title") %></h1>
<p><%= t(".name_info", name: user.username) %></p>

And in the locale file:

title: Title Of This Page
name_info: Here is your name, %{name}.

This will make these strings available for translations, 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.