Save method behaviour changed?

I have this code in a working RoR-3.1 app:

save

Override AR save method to catch DBMS specific errors

such as uniqueness constraint violations

def save
super
rescue ActiveRecord::StatementInvalid => this_exception
errors.add( currency_code, hll_ar_exception( this_exception ) )
false
end

In RoR-3.2.12 this no longer works. Once I pass a save involving a
duplicate record it never returns to the calling method. For example:

def save
super
fail( " die die die " )
rescue ActiveRecord::StatementInvalid => this_exception

produces no output and does not throw an exception but in the log file I
see this none-the-less:

PG::Error: ERROR: duplicate key value violates unique constraint
“idxu_currencies_currency_code”
DETAIL: Key (currency_code)=(JPY) already exists.

How do I get the old behaviour back? Calling save! instead super does
not
change the outcome.

On Tue, Mar 5, 2013 at 1:32 PM, byrnejb [email protected] wrote:

  false

produces no output and does not throw an exception but in the log file I see
this none-the-less:

PG::Error: ERROR: duplicate key value violates unique constraint
“idxu_currencies_currency_code”
DETAIL: Key (currency_code)=(JPY) already exists.

How do I get the old behaviour back? Calling save! instead super does not
change the outcome.

I don’t know the answer to your question, but I’m wondering if you can
circumvent the exception altogether by using valid? to see if it’s a
valid record before attempting the save?

On Tue, March 5, 2013 19:13, tamouse mailing lists wrote:

  errors.add( currency_code, hll_ar_exception( this_exception )
fail( " die die die " )

How do I get the old behaviour back? Calling save! instead super
does not
change the outcome.

I don’t know the answer to your question, but I’m wondering if you can
circumvent the exception altogether by using valid? to see if it’s a
valid record before attempting the save?

Rails validation for duplicate records is, to put it bluntly, a joke.
The code I wrote is intended to compensate for that fact by using the
DBMS as it is intended to be used. Up to the current version of Rails
this worked as I intended. Now it does not. I simply want to
discover what has changed and how I get around it.


*** E-Mail is NOT a SECURE channel ***
James B. Byrne mailto:[email protected]
Harte & Lyne Limited http://www.harte-lyne.ca
9 Brockley Drive vox: +1 905 561 1241
Hamilton, Ontario fax: +1 905 561 0757
Canada L8E 3C3

On Tue, Mar 5, 2013 at 7:32 PM, byrnejb [email protected] wrote:

I have this code in a working RoR-3.1 app:

save

Override AR save method to catch DBMS specific errors

such as uniqueness constraint violations

Where is this code? in a model, in module that is included into various
models, somewhere else?

As an aside recent versions of rails raise ActiveRecord::RecordNotUnique
in
such cases, although this is a subclass of
ActiveRecord::StatementInvalid
so shouldn’t change behaviour as far as you’re concern. You’re also
changing the signature of save although I don’t think that is related to
the problem at hand.

Fred

On Wed, March 6, 2013 04:54, Frederick C. wrote:

As an aside recent versions of rails raise
ActiveRecord::RecordNotUnique in
such cases, although this is a subclass of
ActiveRecord::StatementInvalid
so shouldn’t change behaviour as far as you’re concern. You’re also
changing the signature of save although I don’t think that is related
to the problem at hand.

On: Tue Mar 5, 2013 1:48 pm ((PST)), “Les N.”
[email protected] lesnightingill wrote:

perhaps the exception being raised is not
ActiveRecord::StatementInvalid.

suggest trying rescue with no exception specified to see if there is a
different exception being raised.

Les

Bingo! Rails-3.2.12 implements code similar to that I was providing
in hll_ar_exception( this_exception ) ) and actually returns the
exact message from PG that I was checking for therein.

def save( * )
begin
puts( “I go” )
super
puts( “I return” )
rescue => e
puts( e.inspect )
false
end
end

Using the default profile…
…I go
#<ActiveRecord::RecordNotUnique: PG::Error: ERROR: duplicate key
value violates unique constraint “idxu_currencies_currency_code”
DETAIL: Key (currency_code)=(JPY) already exists.
: INSERT INTO “currencies” (“changed_at”, “changed_by”, “created_at”,
“created_by”, “currency_code”, “currency_name”, “discount_factor”,
“effective_from”, “fx_accounting_factor”, “fx_accounting_margin”,
“is_payable”, “is_receivable”, “premium_factor”, “superseded_after”)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
RETURNING “id”>
…F-

(::slight_smile: failed steps (::slight_smile:

Mystery solved. Thanks.


*** E-Mail is NOT a SECURE channel ***
James B. Byrne mailto:[email protected]
Harte & Lyne Limited http://www.harte-lyne.ca
9 Brockley Drive vox: +1 905 561 1241
Hamilton, Ontario fax: +1 905 561 0757
Canada L8E 3C3

On Wed, March 6, 2013 04:54, Frederick C. wrote:

Where is this code? in a model, in module that is included into
various models, somewhere else?

It is contained in a model:

class Currency < ActiveRecord::Base
include HLLActiveRow

after_save( :save_errors )
. . .

save

Override AR save method to catch DBMS specific errors

such as uniqueness constraint violations

def save( * )
begin
puts( “I go” )
super
puts( “I return” )
rescue ActiveRecord::StatementInvalid => this_exception
errors.add( currency_code, hll_ar_exception( this_exception ) )
# errors.add_to_base(hll_ar_exception(this_exception))
false
end
end
. . .

I see that in the new persistence layer save is now deifined thus:

File activerecord/lib/active_record/persistence.rb, line 82

def save(*)
begin
create_or_update
rescue ActiveRecord::RecordInvalid
false
end
end

Which bears some similarity to what I was doing for previous versions.
The rescue was added to persistence.rb in this commit two years ago:

But my code has been working subsequent to this up to v3.2. Something
else has changed to cause the effect I am now experiencing. The main
problem from my point of view is that I expect the save call to return
to the invoking method immediately after the point super is invoked
and that is not happening. That is what I find astonishing.

As an aside recent versions of rails raise
ActiveRecord::RecordNotUnique in
such cases, although this is a subclass of
ActiveRecord::StatementInvalid
so shouldn’t change behaviour as far as you’re concern. You’re also
changing the signature of save although I don’t think that is related
to the problem at hand.

As far as I can see, save rescues but does not re-raise such
exceptions so I do not know where it is being returned from.


*** E-Mail is NOT a SECURE channel ***
James B. Byrne mailto:[email protected]
Harte & Lyne Limited http://www.harte-lyne.ca
9 Brockley Drive vox: +1 905 561 1241
Hamilton, Ontario fax: +1 905 561 0757
Canada L8E 3C3