Search code examples
ruby-on-railsrubyruby-on-rails-5upgraderuby-2.4

Ruby 2.4 module name conflict with my model class name


I'm upgrading Ruby's version from 2.3.8 to 2.4.4 on Rails 5.2.3.

When I start the application I get this error:

app/models/warning.rb:1:in `<main>': Warning is not a class (TypeError)

when called on console: Warning.class => Module

But in fact it is one of my models called Warning.

I saw in released notes an introduction to a new module on ruby 2.4 called Warning. but how can I avoid this conflict without renaming my model with migrations?


Solution

  • Warning module is used for overriding ruby warn method. To temporarily get around the error - you can undefine the constant before defining your model:

    Object.send(:remove_const, :Warning)
    

    runnable test:

    require "bundler/inline"
    gemfile(true) do
      source "https://rubygems.org"
      gem "activerecord", "5.2.3"
      gem "sqlite3", "~> 1.3.6"
    end
    
    require "active_record"
    require "minitest/autorun"
    require "logger"
    
    ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
    ActiveRecord::Schema.define do
      create_table(:warnings, force: true){|t| t.string  :name }
    end
    
    RubyWarning = Warning
    Object.send(:remove_const, :Warning)
    
    class Warning < ActiveRecord::Base
    end
    
    def RubyWarning.warn(str)
      puts "still works: #{str}"
    end
    
    class SomeTest < Minitest::Test
      def test_stuff
        wrn = Warning.create name: 'test'
        assert_equal(wrn.name, 'test')
        warn "Test warn"
      end
    end