Skip to content
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/DateAndTimeColumnName cop #335

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

fatkodima
Copy link
Contributor

Inspired by https://github.com/thoughtbot/guides/tree/master/rails

Name date columns with _on suffixes.
Name datetime columns with _at suffixes.
Name time columns (referring to a time of day with no date) with _time suffixes.

This enforces consistency and it is easier to tell the type from name without referring to db schema.

@koic
Copy link
Member

koic commented Aug 23, 2020

There is reason why it is hard to apply by default. Updating db/migrate files that has already been migrated will result in schema mismatch.

@koic
Copy link
Member

koic commented Aug 23, 2020

#277 also has the same problem.

@fatkodima
Copy link
Contributor Author

We can add a config option (something like StartAfter: 20200907202002) from which version to start checking.

@koic
Copy link
Member

koic commented Aug 23, 2020

Yeah, I also considered the timestamp value. Perhaps setting to .rubocop.yml is expensive to maintain. It may be better to use the timestamp value from db/schema.rb. But I have not yet fully considered false positives 😅

@andyw8 andyw8 mentioned this pull request Oct 4, 2020
9 tasks
@pirj
Copy link
Member

pirj commented Dec 25, 2021

@fatkodima ping

@fatkodima
Copy link
Contributor Author

@pirj

We can add a config option (something like StartAfter: 20200907202002) from which version to start checking.

So I need to implement this?

@pirj
Copy link
Member

pirj commented Dec 25, 2021

Another option that does not require configuration is inspecting db/*schema.rb files. Plural because there can many with multiple DB support.

@pirj
Copy link
Member

pirj commented Dec 25, 2021

Oh, that won't work, as schemas have all legacy columns. Yes, I believe the path taken in #277 is fine.

Copy link
Member

@pirj pirj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you.
Some minor notes only.

PS Plus the StartAfterMigrationVersion options is needed.

Enabled: pending
VersionAdded: '2.8'
Include:
- db/migrate/**/**.rb
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple db setup reads migrations_paths: from config/database.yml. I'm not sure if there's a convention on how to place them. Mine are usually in db/secondary_migrate/*.rb.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to

  Include:
    - db/**/*.rb

like in #277
That way it will check all migration files (I hope no one places migration files using migrations_paths: into other folders than db/ 😄 )

config/default.yml Outdated Show resolved Hide resolved
docs/modules/ROOT/pages/cops.adoc Outdated Show resolved Hide resolved
def_node_matcher :migration_base?, <<~PATTERN
{
(send (const (const nil? :ActiveRecord) :Migration) :[] _)
(const (const nil? :ActiveRecord) :Migration)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if some projects use a common ApplicationMigration 🤔
Is this check really necessary if we already know that we're inspecting db/migrations/*.rb?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this change

 Include:
    - db/**/*.rb

we should at least ignore schema.rb files. It is also possible (but very unlikely) to have some other files there, except migration files. Better to double check, I think.

lib/rubocop/cop/rails/date_and_time_column_name.rb Outdated Show resolved Hide resolved
subject(:cop) { described_class.new }

context 'when `add_column` method' do
described_class::TYPE_TO_SUFFIX.each do |type, suffix|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't fail if you remove or add entries to TYPE_TO_SUFFIX. It also requires the reader of the spec to look it up in the implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the way how similar things are tested in many places in the rubocop and rubocop-rails (for example,

described_class::TYPES.each do |type|
). I was just stayed consistent with that style.

spec/rubocop/cop/rails/date_and_time_column_name_spec.rb Outdated Show resolved Hide resolved
end
end

context 'when `<type>` method' do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be interpolated with a real type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was meant method calls like t.integer ... or t.text ... etc. Changed it to t.<type> to be a little more clear.

`time` - with `_time` suffix.
Enabled: pending
VersionAdded: '<<next>>'
StartAfterMigrationVersion: null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
StartAfterMigrationVersion: null

end
end
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1383 was integrated. Can you remove this module?

# t.column :visited_on, :date
# t.time :start_time
#
# @example StartAfterMigrationVersion: 20211007000001
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this example?

# add_column :orders, :created_on, :datetime
#
class DateAndTimeColumnName < Base
include StartAfterMigrationVersion
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
include StartAfterMigrationVersion
prepend MigrationsHelper

def in_migration?(node)
class_node = node.each_ancestor(:class).first
migration_base?(class_node&.parent_class)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method can be removed and replaced with RuboCop::Cop::MigrationsHelper#in_migration?.

@koic
Copy link
Member

koic commented Dec 26, 2024

This naming rule can probably be added to the Rails Style Guide.

@fatkodima fatkodima force-pushed the date_and_time_column_name-cop branch from d3ab782 to d7f6c33 Compare December 26, 2024 09:57
@fatkodima
Copy link
Contributor Author

Updated PR with the suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants