Rails 5.1 - ActiveRecord::RecordNotUnique.new wrong number of arguments

432 views Asked by At

Upgrading from Rails 4 to Rails 5.1. Have this running rspec test:

Failure/Error: let(:exception)   { 
ActiveRecord::RecordNotUnique.new("oops", Mysql2::Error) }

ArgumentError:
wrong number of arguments (given 2, expected 0..1)

It seems the syntax of ActiveRecord exceptions has changed in Rails 5? I don't think this was mentioned in any 'what is new in Rails 5' articles I read. Google found naught, nor a site with source code.

1

There are 1 answers

0
xxjjnn On

Using bundle open rails (assuming using bundler) shows source code locally. Moving up a directory, you will be in somewhere like ~/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems (if using rbenv).

Searching this directory will find the definitions which will explain. Search example using Vim and Silver Searcher:

:Ag 'class RecordNotUnique' ~/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems

/Users/xxjjnn/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/errors.rb|98 col 3| class RecordNotUnique < WrappedDatabaseException
/Users/xxjjnn/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/activerecord-5.1.3/lib/active_record/errors.rb|109 col 3| class RecordNotUnique < WrappedDatabaseException

and from here we can see that in Rails 5.1 the method now no longer takes two arguments:

# BOTH
class RecordNotUnique < WrappedDatabaseException
end
class WrappedDatabaseException < StatementInvalid
end

# 4.2.7.1
class StatementInvalid < ActiveRecordError
  def initialize(message = nil, original_exception = nil)
    if original_exception
      ActiveSupport::Deprecation.warn("Passing #original_exception is deprecated and has no effect. " \
                                      "Exceptions will automatically capture the original exception.", caller)
    end
    super(message || $!.try(:message))
  end  
  def original_exception
    ActiveSupport::Deprecation.warn("#original_exception is deprecated. Use #cause instead.", caller)
    cause
  end
end
# 5.1.3
class StatementInvalid < ActiveRecordError
  def initialize(message = nil)
    super(message || $!.try(:message))
  end
end

This technique of grepping the source can fix many problems like this.