-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Remove rules that can be replaced with a linter. #792
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,8 @@ | ||
| # Controllers | ||
|
|
||
| - Controllers handle HTTP only: receive request, delegate to model, return response. | ||
| - Actions should not exceed 10 lines (excluding strong params). Longer actions often signal business logic that belongs in a model or PORO. | ||
| - Avoid long actions, since they often signal business logic that belongs in a model or PORO. | ||
| - Maximum one instance variable per action. | ||
| - No business logic, calculations, email sending, or multi-object operations in controllers. | ||
| - Always use strong parameters. Never `params.permit!`. | ||
| - Return `status: :unprocessable_entity` on failed form renders (required by Turbo). | ||
| - Prefer RESTful routes. Custom verb actions (e.g., post "activate") usually mean a missing noun/resource (e.g., resource :trial, only: [:create]). | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,8 +1,6 @@ | ||||||
| # Database & Migrations | ||||||
|
|
||||||
| - Always use the `rails generate migration` command to create migration files. | ||||||
| - Migrations must be reversible. | ||||||
| - Add `null: false` and database-level defaults where appropriate. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is a nice hint to the LLMs to prefer null: false where appropriate because as you mention in your description, there is no hard rule for this. It depends.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jaredlt we should be covered by Rails/NotNullColumn.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I should elaborate. I like the idea of having the linter bring this to the attention of the author just to be safe. They can always decide to add a comment disabling it in that migration.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I agree with this. I do think we need to experiment with what works for the linter. We want it to be right most of the time rather than feel like we're fighting it. That cop doesn't help remind us that ideally we want to use null: false for most columns. It only triggers if an add_column has null: false without a default as well. So if you just add_column without a null: false it will succeed.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stevepolitodesign would you be open to keeping the My reading of that cop is that it doesn't enforce us to using I'm also open to this being enforced via lint the future with some form of opt out. I just don't know what that looks like exactly yet. I think the rest of the PR looks great. |
||||||
| - Use `text` over `string` if length varies significantly. | ||||||
| - Wrap multi-record operations in transactions. Use `save!` (bang) inside transactions. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can the direction to use
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know enough about RuboCop here but aren't there valid reasons why you wouldn't want to use the bang version of these methods? If we enforce that via lint then do we need to add exclusions everywhere we don't want them?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are valid reasons why you wouldn't want to use the bang version of a method, and the one I've run across the most is because you're calling some library that does not have a bang method defined for the thing you need to call. For this PR, removing the guidance from CLAUDE.md simplifies the LLM's task and pushes it to the linter and the human, in which case you add an exception if necessary.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Surfacing errors is a very common case for non-bang save/update methods. I'm worried about us scattering our codebases with exceptions for this very common case. This goes to my point about wanting to ensure we don't fee like we're fighting the linter
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two things:
The goal is to enforce rules at an automatic level and let a human decide about exceptions, not rely on an agent to remember a hint for something that could be catastrophic. So the change here is don't give hints to the agent where an automatic tool will enforce things. Give hints to the agent where the automatic tool cannot guide it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that we have LLMs the cost of creating fancier lint rules has gone down a lot. I could imagine a lint rule that requires |
||||||
| - Keep scopes as one-liners. Complex queries belong in search/query objects. | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,5 +11,4 @@ | |
| - Factories: only required attributes with sensible defaults. Start in `spec/factories.rb`. | ||
| - Shoulda Matchers for validations and associations. | ||
| - WebMock blocks all external HTTP in tests — always stub external requests. | ||
| - One `expect` per `it` block. Max 2 levels of context nesting. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with removing this one but I do wonder about enforcing the lint rules. Sometimes an extra expect in the same test tells the story better. Sometimes an extra context wrapped around a test tells the story better. |
||
| - Never test private methods directly. Never stub the system under test. | ||
Uh oh!
There was an error while loading. Please reload this page.