Follow rails conventions

Always write idiomatic rails.

Recommendations:

  • Use generators when possible. rails generate scaffold will be faster and more reliable than writing code directly.
  • Use resources blocks in routes.rb when possible
  • Always follow rails conventions for how actions are implemented in controllers. It should look like it was created by a rails generator: standard names, {model}_params, respond_to blocks, etc

Keep complexity in the right places

  • Controllers should be extremely thin wrappers. If controller methods are getting long, they likely belong elsewhere
  • Use @model.as_json for serialization rather than manually building attribute hashes in controllers
  • Models are allowed to be larger
  • If a model gets too large, split it up into well-scoped mixins. For example, api_token.rb has include ApiTokenMixins::ZulipAuditNotifications — this is a good pattern.
  • Put helpers used by both models and controllers in app/lib
  • Most “task” oriented things make sense as a job in app/jobs

Test with RSpec

Use rspec to write tests. Tests are generally good, and err on the side of writing them, but still be judicious and focused.

When tests are good:

  • Tests are recommended for any critical flows (eg auth)
  • Any hairy methods with lots of complexity
  • Helpers that will be re-used in many places

When NOT to write tests:

  • Thin controllers that are delegating logic elsewhere
  • Tests that would simply repeat the logic of the implementation

Miscellaneous recommendations:

  • Use after_commit, on: create etc in most places instead of after_save. This ensures the database commit goes through which is what we want in 90% of callbacks.
  • Use .toys for one-off scripts. This is based on the toys gem.