Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4, Ruby 2.7.1 schema.rb shows "Could not dump table because of following FrozenError"

After upgrading to Ruby 2.7.1 my schema.rb is peppered with the following warnings for multiple tables:

# Could not dump table "pages" because of following FrozenError
#   can't modify frozen String: "false"

# Could not dump table "proxies" because of following FrozenError
#   can't modify frozen String: "true"

I've searched high and low for a solution and have checked (as far as I'm able) the migrations, of which there are many. Downgrading Ruby at this staging isn't an option.

Anyone has a similar situation and managed to resolve it?

like image 489
padz Avatar asked Jun 25 '20 08:06

padz


1 Answers

If someone is still looking for this.

The error is because in the old version of rails the schema dumper used the to_s to convert database default column value to string and then perform operations on that string. But in ruby 2.7 the to_s method for nil, true and false return a frozen string and hence the FrozenError, so if upgrading rails version is not an option you can just put this in an initializer to override the schema dumper method to use the dup instead of actual string.

module ActiveRecord
  module ConnectionAdapters
    module ColumnDumper
      def prepare_column_options(column, types)
        spec = {}
        spec[:name]      = column.name.inspect
        spec[:type]      = column.type.to_s
        spec[:null]      = 'false' unless column.null

        limit = column.limit || types[column.type][:limit]
        spec[:limit]     = limit.inspect if limit
        spec[:precision] = column.precision.inspect if column.precision
        spec[:scale]     = column.scale.inspect if column.scale

        default = schema_default(column).dup if column.has_default?
        spec[:default]   = default unless default.nil?

        spec
      end
    end
  end
end

like image 153
Abdul Rehman Avatar answered Nov 15 '22 03:11

Abdul Rehman