-
-
Notifications
You must be signed in to change notification settings - Fork 263
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
Add new Rails/ReversibleMigrationMethodDefinition
cop
#457
Add new Rails/ReversibleMigrationMethodDefinition
cop
#457
Conversation
78cbc83
to
83225a6
Compare
Rails/ImplementedMigration
cop
I haven't tried it, but would https://github.com/ankane/strong_migrations help prevent any of these issues? |
Good thought. I don't believe it can be configured to catch these cases (we use it at our company and have these issues). From what I understand strong migrations uses instrumentation to enforce best practices. I don't think it's possible to catch these types of issues with instrumentation as it cannot catch issues on methods not called? |
83225a6
to
08dc1a4
Compare
CHANGELOG.md
Outdated
@@ -4,6 +4,7 @@ | |||
|
|||
### New features | |||
|
|||
* [#457](https://github.com/rubocop/rubocop-rails/pull/457): New cop `Rails/ImplementedMigration` checks for migrations that have a typo in a method name or are half implemented. ([@leonp1991][]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* [#457](https://github.com/rubocop/rubocop-rails/pull/457): New cop `Rails/ImplementedMigration` checks for migrations that have a typo in a method name or are half implemented. ([@leonp1991][]) | |
* [#457](https://github.com/rubocop/rubocop-rails/pull/457): Add new `Rails/ReversibleMigrationMethodDefinition` cop. ([@leonp1991][]) |
config/default.yml
Outdated
@@ -362,6 +362,11 @@ Rails/IgnoredSkipActionFilterOption: | |||
Include: | |||
- app/controllers/**/*.rb | |||
|
|||
Rails/ImplementedMigration: | |||
Description: 'Checks for migrations that have a typo in a method name or are half implemented.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update the description?
Description: 'Checks for migrations that have a typo in a method name or are half implemented.' | |
Description: 'Checks whether the migration implements either a `change` method or both an `up` and a `down` method. |
config/default.yml
Outdated
Rails/ImplementedMigration: | ||
Description: 'Checks for migrations that have a typo in a method name or are half implemented.' | ||
Enabled: false | ||
VersionAdded: '2.10' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add Include
path?
VersionAdded: '2.10' | |
VersionAdded: '2.10' | |
Include: | |
- db/migrate/*.rb |
def chance # <----- typo | ||
# migration | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think typos are not the main focus of the cop, so can you remove this example?
# good | ||
class SomeMigration < ActiveRecord::Migration[6.0] | ||
def change | ||
# migration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# migration | |
# reversible migration |
# # down migration | ||
# end | ||
# end | ||
class ImplementedMigration < Base |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name ImplementedMigration
looks abstract in purpose. How about the name ReversibleMigrationMethodDefinition
?
class ImplementedMigration < Base | |
class ReversibleMigrationMethodDefinition < Base |
MSG = 'Migrations must contain either a change method, or ' \ | ||
'both an up and a down method.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you enclose method names in backticks?
MSG = 'Migrations must contain either a change method, or ' \ | |
'both an up and a down method.' | |
MSG = 'Migrations must contain either a `change` method, or ' \ | |
'both an `up` and a `down` method.' |
return if change_method?(node) | ||
return if up_and_down_methods?(node) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you refactor it?
return if change_method?(node) | |
return if up_and_down_methods?(node) | |
return if change_method?(node) || up_and_down_methods?(node) |
RUBY | ||
end | ||
|
||
it 'registers an offense with a typo\'d change method' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it 'registers an offense with a typo\'d change method' do | |
it "registers an offense with a typo'd change method" do |
class SomeMigration < ActiveRecord::Migration[6.0] | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | ||
|
||
def up |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the redundant blank line in this PR' test examples?
class SomeMigration < ActiveRecord::Migration[6.0] | |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | |
def up | |
class SomeMigration < ActiveRecord::Migration[6.0] | |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | |
def up |
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[5.1] | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | ||
|
||
def chance | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
|
||
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[7.1] | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | ||
|
||
def chance | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the redundant test case and leave only one of them?
expect_offense(<<~RUBY) | |
class SomeMigration < ActiveRecord::Migration[5.1] | |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | |
def chance | |
add_column :users, :email, :text, null: false | |
end | |
end | |
RUBY | |
expect_offense(<<~RUBY) | |
class SomeMigration < ActiveRecord::Migration[7.1] | |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | |
def chance | |
add_column :users, :email, :text, null: false | |
end | |
end | |
RUBY | |
expect_offense(<<~RUBY) | |
class SomeMigration < ActiveRecord::Migration[5.2] | |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | |
def chance | |
add_column :users, :email, :text, null: false | |
end | |
end | |
RUBY |
expect_no_offenses(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[5.2] | ||
def change | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
|
||
expect_no_offenses(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[7.1] | ||
def change | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto :-)
expect_no_offenses(<<~RUBY) | |
class SomeMigration < ActiveRecord::Migration[5.2] | |
def change | |
add_column :users, :email, :text, null: false | |
end | |
end | |
RUBY | |
expect_no_offenses(<<~RUBY) | |
class SomeMigration < ActiveRecord::Migration[7.1] | |
def change | |
add_column :users, :email, :text, null: false | |
end | |
end | |
RUBY | |
expect_no_offenses(<<~RUBY) | |
class SomeMigration < ActiveRecord::Migration[5.2] | |
def change | |
add_column :users, :email, :text, null: false | |
end | |
end | |
RUBY |
|
||
it 'registers offenses correctly with any migration class' do | ||
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[5.1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rails has not officially maintained Rails 5.1 series.
https://guides.rubyonrails.org/maintenance_policy.html
RuboCop Rails also has negative support, so please specify it to 5.2 or higher for the example.
RUBY | ||
|
||
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[7.1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's just my two cents. Rails 7.1 is a world no one has seen yet 😅 Can you update to 6.1?
class SomeMigration < ActiveRecord::Migration[7.1] | |
class SomeMigration < ActiveRecord::Migration[6.1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol this is true it is not in the world yet and may not ever be a specific version (however likely). Was just trying to make sure it wont break on a future release 🤠.
9213485
to
c615bd4
Compare
@koic I appreciate all the feedback. I think the new name has made the cop's intention much clearer. The latest version should address all comments and anywhere else that made sense after. |
Rails/ImplementedMigration
copRails/ReversibleMigrationMethodDefinition
cop
Thanks! |
Description: 'Checks whether the migration implements either a `change` method or both an `up` and a `down` method.' | ||
Enabled: false | ||
VersionAdded: '2.10' | ||
include: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include
typo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, without it it flags all Ruby files :=)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😅 My bad thanks @rhymes
This cop attempts to automate part of the review process of rails migrations. Two example cases this cop helps prevent are:
chance
instead ofchange
These can both be a bad time when not caught before merging to production.
Case 1 can lead to the deployment of code that relies on a column that has not been added yet.
Case 2 can lead to hard to revert faulty deployments.
Rails/ReversibleMigrationMethodDefinition
copBefore submitting the PR make sure the following are checked:
[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).and description in grammatically correct, complete sentences.
bundle exec rake default
. It executes all tests and RuboCop for itself, and generates the documentation.