Why can't we access local variable inside rescue?
Local Variable
begin
transaction #Code inside transaction
object = Class.new attributes
raise unless object.save!
end
rescue
puts object.error.full_messages # Why can't we use local varible inside rescue ?
end
Instance Variable
begin
transaction #Code inside transaction
@object = Class.new attributes
raise unless @object.sav开发者_StackOverflow中文版e!
end
rescue
puts @object.error.full_messages # This is working fine.
end
You most certainly can access local variables defined in a begin
, in the corresponding rescue
block (assuming of course, the exception has been raised, after the variable was set).
What you can't do is access local variables that are defined inside a block, outside of the block. This has nothing to do with exceptions. See this simple example:
define transaction() yield end
transaction do
x = 42
end
puts x # This will cause an error because `x` is not defined here.
What you can do to fix this, is to define the variable before the block (you can just set it to nil) and then set it inside the block.
x = nil
transaction do
x = 42
end
puts x # Will print 42
So if you change your code like this, it will work:
begin
object = nil
transaction do #Code inside transaction
object = Class.new attributes
raise unless object.save!
end
rescue
puts object.error.full_messages # Why can't we use local varible inside rescue ?
end
You can pick up error message from ActiveRecord::RecordInvalid. It can be seen on official document example here.
https://api.rubyonrails.org/v6.1.3.2/classes/ActiveRecord/RecordInvalid.html
begin
transaction
Class.create! attributes
end
rescue ActiveRecord::RecordInvalid => invalid
puts invalid.record.error.full_messages
end
精彩评论