環境
Rails: 7.1.2
Sorcery: 0.16.5
現象
rails g sorcery:install
を実行すると
undefined method
timestamped_migrations' for ActiveRecord::Base:Class (NoMethodError)`が起きてmigrationファイルが作成されない
ログ
root@0c0d3f43df2c:/app# bin/rails g sorcery:install
create config/initializers/sorcery.rb
generate model User --skip-migration
rails generate model User --skip-migration
invoke active_record
create app/models/user.rb
insert app/models/user.rb
unchanged app/models/user.rb
/usr/local/bundle/gems/activerecord-7.1.2/lib/active_record/dynamic_matchers.rb:22:in `method_missing': undefined method `timestamped_migrations' for ActiveRecord::Base:Class (NoMethodError)
from /usr/local/bundle/gems/sorcery-0.16.5/lib/generators/sorcery/install_generator.rb:78:in `next_migration_number'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/generators/migration.rb:43:in `set_migration_assigns!'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/generators/migration.rb:59:in `migration_template'
from /usr/local/bundle/gems/sorcery-0.16.5/lib/generators/sorcery/install_generator.rb:65:in `copy_migration_files'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/command.rb:28:in `run'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/invocation.rb:127:in `invoke_command'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/invocation.rb:134:in `block in invoke_all'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/invocation.rb:134:in `each'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/invocation.rb:134:in `map'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/invocation.rb:134:in `invoke_all'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/group.rb:232:in `dispatch'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/base.rb:584:in `start'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/generators.rb:261:in `invoke'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/commands/generate/generate_command.rb:26:in `perform'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/command.rb:28:in `run'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor/invocation.rb:127:in `invoke_command'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/command/base.rb:178:in `invoke_command'
from /usr/local/bundle/gems/thor-1.3.0/lib/thor.rb:527:in `dispatch'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/command/base.rb:73:in `perform'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/command.rb:71:in `block in invoke'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/command.rb:149:in `with_argv'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/command.rb:69:in `invoke'
from /usr/local/bundle/gems/railties-7.1.2/lib/rails/commands.rb:18:in `<main>'
from <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
from <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
from /usr/local/bundle/gems/bootsnap-1.17.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from bin/rails:4:in `<main>'
対処法
※Sorceryのissueに上がっており、プルリクも上がっているのでもうちょいで対応してくれそうな雰囲気なので暫定的な対応になります。
issue: https://github.com/Sorcery/sorcery/issues/353
pull_request: https://github.com/Sorcery/sorcery/pull/352
対応方法
コマンドを実行するときだけconfig/application.rb
の一番下にコードを追加します。
コマンド実行後は削除してください。
config/application.rb
#〜〜中略〜〜
class ActiveRecord::Base
singleton_class.attr_accessor :timestamped_migrations
self.timestamped_migrations = true
end
コードを追加後下記コマンドを実行してください
rails g sorcery:install
以下のようにコマンドが最後まで正常に終了すれば成功です
root@0c0d3f43df2c:/app# bin/rails g sorcery:install
identical config/initializers/sorcery.rb
generate model User --skip-migration
rails generate model User --skip-migration
invoke active_record
The name 'User' is either already used in your application or reserved by Ruby on Rails. Please choose an alternative or use --skip-collision-check or --force to skip this check and run this generator again.
unchanged app/models/user.rb
unchanged app/models/user.rb
create db/migrate/20231212081037_sorcery_core.rb
コマンド実行後は追加したコードは削除してください
コード全体ではこのようになります
require_relative "boot"
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_mailbox/engine"
require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module App
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 7.1
# Please, add to the `ignore` list any other `lib` subdirectories that do
# not contain `.rb` files, or that should not be reloaded or eager loaded.
# Common ones are `templates`, `generators`, or `middleware`, for example.
config.autoload_lib(ignore: %w(assets tasks))
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files
# in config/environments, which are processed later.
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
# Don't generate system test files.
config.generators.system_tests = nil
end
end
class ActiveRecord::Base
singleton_class.attr_accessor :timestamped_migrations
self.timestamped_migrations = true
end
原因
Sorceryのプルリクエストを見るとわかりますが、Sorceryで使用しているtimestamped_migrations
がActiveRecord::Base
からActiveRecord
のclassメソッドに変更になったことによるバグらしいです。
railsのgemを見てみましたが、6.0系ではActiveRecord::Base
に生えているっぽいので7系のどこかのタイミングで変わったみたいです。
最後に
あくまで暫定的な対応なのでSorcery側の対応が終わったらgemをアップデートしてもらえれば解決するかと思います。