Created
September 10, 2026 08:52
-
-
Save s-mage/0ffd9be323d19f580f4887d2494b4933 to your computer and use it in GitHub Desktop.
coding-conventions.md from cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| description: Coding conventions and style preferences | |
| alwaysApply: true | |
| --- | |
| # Coding Conventions | |
| ## Rails | |
| - Prefer Rails conventions (named routes, resourceful controllers, callbacks, etc.) | |
| - Prefer ActiveRecord queries and scopes over raw SQL | |
| - Don't create scopes that just wrap a single `where` on a column -- `where(column:)` is shorter to use and doesn't need a custom name | |
| - Lean controllers -- keep them focused and short | |
| - If you change a migration, rollback, make a change, then migrate. Never change migrations that are in the main branch already. | |
| - Migrations in one PR should be "squashed" into one. Change existing migration instead of adding a new one unless the migration is already in the main branch. | |
| - Schema dumps should only contain changes caused by the migrations in the current work. Revert incidental column-order or formatting changes before handing off. | |
| - use strict locals in views: you can write a magic comment that defines local variables, format: `<%# locals: (var1:, var2: "default_value") -%>` | |
| - avoid creating variables, constants, methods or scopes used once. Prefer putting such things into the place of usage. | |
| ### Flash Messages | |
| - Don't show obvious success messages - if a user creates/updates/deletes something and it succeeds, the result is self-evident from the redirect (e.g., seeing the created item, being back on the list page) | |
| - Do show error/alert messages - users need to know when something fails and why | |
| - Do show success messages when the outcome isn't immediately visible (e.g., background job queued, email sent) | |
| ### Forms | |
| - Use Rails form helpers (`f.text_field`, `f.submit`, `number_field_tag`, `select_tag`, etc.) -- never raw `<input>` or `<select>` HTML tags. Prefer Simple Form `simple_form_for` to Rails `form_for` to `<form>` | |
| ## HTML / CSS | |
| - Prefer BEM naming for CSS classes over Tailwind utility classes when you have a good name for a component. Keep Tailwind for utility classes. A component class is worthwhile if it can be applied more than once, possibly with variations. See existing CSS files, especially in the nc engine, for examples. | |
| - Minimize DOM nodes -- avoid unnecessary wrapper divs | |
| - Single node with text content: use `tag.div t(".key"), class: "..."` one-liner instead of open/close tags with ERB inside | |
| - Keep views at one layer of abstraction. When a section of a template drops into a deeper level of detail (e.g., a nested loop with its own markup), extract it into a partial. Don't nest partials inside partials aggressively. | |
| - Spacing: gaps between sibling sections should be larger than internal spacing within a section (outer > inner, recursively) | |
| - Default text colors are usually fine -- don't mute or gray out text unless there's a strong reason | |
| - margin considered harmful. Use gaps and paddings. | |
| ## Helpers | |
| - Conditional CSS class logic belongs in helpers, not in views | |
| ## i18n | |
| - Always use `t()` / I18n for user-facing strings -- no hardcoded text in views | |
| - Use lazy lookup (`t(".key")`) in views and partials -- Rails resolves the key from the template path automatically | |
| ## JavaScript | |
| - Prefer Stimulus controllers over custom JS | |
| ## Testing & Quality | |
| - When fixing a bug, write a test that covers the fix | |
| - Run tests and `bundle exec rubocop -A` before handing off work | |
| - Never manually clean the database in tests (`delete_all`, `destroy_all` in setup/teardown) -- Rails handles this via transactions. | |
| - If test changes a configuration variable that is initially set in ENV, reset it in `ensure` block of the test | |
| - Use `assert_difference` / `assert_no_difference` to verify record counts | |
| - Use fixtures. If you need to create many records, consider copying fixtures like MyModel.create!(my_models(:fixture_name).attributes.except(:id, :created_at, ...)) | |
| ## Data | |
| - Minimize data transformations -- keep data in its original shape when possible | |
| - Avoid gratuitous format conversions (e.g., camelCase keys) unless the consumer requires it | |
| - When we own the full data path, establish shape once at the source or boundary (e.g. `symbolize_keys` when parsing JSON) instead of defensively re-normalizing (`to_h`, `symbolize_keys`, type coercion) in every downstream consumer | |
| - Pass data in the expected shape from the producer; consumers should not mutate inputs to coerce them into place | |
| ## General | |
| - Never run `git commit`. | |
| - Before adding a manual validation or guard, check whether Rails (or the relevant framework) already rejects bad values—e.g. ActiveRecord enums raise on invalid assignment—and whether an invalid value can realistically occur. Lean on the framework, no duplicating checks. | |
| - `frozen_string_literal: true` on all Ruby files | |
| - Use Ruby shorthand hash syntax when key and value share the same name: `{ f: }` not `{ f: f }`, `method(name:)` not `method(name: name)` | |
| - Follow existing project conventions (namespacing, `nmx-` component prefixes, etc.) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment