1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Add skip-collision-check option to generator

Until Rails 5.2, generators can run same name multi times without destroying.
But Rails 6.0(with Zeitwerk) can't this. In Rails 6.0, an error occurs
due to class name collision check.

The check uses `const_defined?`, which assumes that the autoload object
is also defined.
https://ruby-doc.org/core-2.6.3/Module.html#method-i-const_defined-3F

It did not work until Rails 5.2, but Zeitwerk seems to be able to
correctly check this against the application's code.

However, this is a little inconvenient if want to run the generator
again like mistake an attribute name(need to run `destoy` before).

In order to solve this, this PR adds an option to skip the collision check.
With this option, you can overwrite files just as did until Rails 5.2.
This commit is contained in:
yuuji.yaginuma 2019-06-29 08:43:16 +09:00
parent a59b230579
commit 6fec4c3a0a
2 changed files with 15 additions and 2 deletions

View file

@ -20,6 +20,8 @@ module Rails
class_option :skip_namespace, type: :boolean, default: false, class_option :skip_namespace, type: :boolean, default: false,
desc: "Skip namespace (affects only isolated applications)" desc: "Skip namespace (affects only isolated applications)"
class_option :skip_collision_check, type: :boolean, default: false,
desc: "Skip collision check"
add_runtime_options! add_runtime_options!
strict_args_position! strict_args_position!
@ -249,6 +251,7 @@ module Rails
# application or Ruby on Rails. # application or Ruby on Rails.
def class_collisions(*class_names) def class_collisions(*class_names)
return unless behavior == :invoke return unless behavior == :invoke
return if options.skip_collision_check?
class_names.flatten.each do |class_name| class_names.flatten.each do |class_name|
class_name = class_name.to_s class_name = class_name.to_s
@ -261,8 +264,8 @@ module Rails
if last && last.const_defined?(last_name.camelize, false) if last && last.const_defined?(last_name.camelize, false)
raise Error, "The name '#{class_name}' is either already used in your application " \ raise Error, "The name '#{class_name}' is either already used in your application " \
"or reserved by Ruby on Rails. Please choose an alternative and run " \ "or reserved by Ruby on Rails. Please choose an alternative or use --skip-collision-check " \
"this generator again." "to skip this check and run this generator again."
end end
end end
end end

View file

@ -198,5 +198,15 @@ module ApplicationTests
assert_no_match "active_record:migration", output assert_no_match "active_record:migration", output
end end
end end
test "skip collision check" do
rails("generate", "model", "post", "title:string")
output = rails("generate", "model", "post", "title:string", "body:string")
assert_match(/The name 'Post' is either already used in your application or reserved/, output)
output = rails("generate", "model", "post", "title:string", "body:string", "--skip-collision-check")
assert_no_match(/The name 'Post' is either already used in your application or reserved/, output)
end
end end
end end