Skip to content

Commit

Permalink
Merge pull request rails#20967 from lxsameer/record_not_found
Browse files Browse the repository at this point in the history
Extra caller details added to ActiveRecord::RecordNotFound
  • Loading branch information
rafaelfranca committed Jul 21, 2015
2 parents b260a27 + d763956 commit efd2410
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 5 deletions.
16 changes: 16 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
* ActiveRecord::RecordNotFound modified to store model name, primary_key and
id of the caller model. It allows the catcher of this exception to make
a better decision to what to do with it. For example consider this simple
example:

class SomeAbstractController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :redirect_to_404

private def redirect_to_404(e)
return redirect_to(posts_url) if e.model == 'Post'
raise
end
end

*Sameer Rahmani*

* Deprecate the keys for association `restrict_dependent_destroy` errors in favor
of new key names.

Expand Down
8 changes: 5 additions & 3 deletions activerecord/lib/active_record/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,13 @@ def find(*ids) # :nodoc:
}
record = statement.execute([id], self, connection).first
unless record
raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
name, primary_key, id)
end
record
rescue RangeError
raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
name, primary_key)
end

def find_by(*args) # :nodoc:
Expand Down Expand Up @@ -199,7 +201,7 @@ def find_by(*args) # :nodoc:
end

def find_by!(*args) # :nodoc:
find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}")
find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}", name)
end

def initialize_generated_modules # :nodoc:
Expand Down
9 changes: 9 additions & 0 deletions activerecord/lib/active_record/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ class ConnectionNotEstablished < ActiveRecordError

# Raised when Active Record cannot find record by given id or set of ids.
class RecordNotFound < ActiveRecordError
attr_reader :model, :primary_key, :id

def initialize(message = nil, model = nil, primary_key = nil, id = nil)
@primary_key = primary_key
@model = model
@id = id

super(message)
end
end

# Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be
Expand Down
4 changes: 3 additions & 1 deletion activerecord/lib/active_record/nested_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,9 @@ def call_reject_if(association_name, attributes)
end

def raise_nested_attributes_record_not_found!(association_name, record_id)
raise RecordNotFound, "Couldn't find #{self.class._reflect_on_association(association_name).klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
model = self.class._reflect_on_association(association_name).klass.name
raise RecordNotFound.new("Couldn't find #{model} with ID=#{record_id} for #{self.class.name} with ID=#{id}",
model, 'id', record_id)
end
end
end
3 changes: 2 additions & 1 deletion activerecord/lib/active_record/relation/finder_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ def find_by(arg, *args)
def find_by!(arg, *args)
where(arg, *args).take!
rescue RangeError
raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range value"
raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
@klass.name)
end

# Gives a record (or N records if a parameter is supplied) without any implied
Expand Down

0 comments on commit efd2410

Please sign in to comment.