matthuhiggins/foreigner

Doesn't raise an exception unless validated first

Closed this issue · 2 comments

I'm trying to get an exception when somebody bypasses validations, but it just fails silently. If I run the validations before hand, however, then I get an ActiveRecord::InvalidForeignKey the next time I try to save without running validations. So basically, if I say state.wavelet_id = nil and call state.save(validate: false) it sets the wavelet_id back to what it was to begin with. This happens the same way when I use valid?, save, and save!, paired with save(validate: false) or update_attribute(wavelet_id: nil).

 > s.wavelet_id = 500001
 => 500001 
 > s
 => #<State id: 6, created_at: "2013-11-04 19:59:25", updated_at: "2013-11-04 19:59:25", wavelet_id: 500001> 
 > s.save(validate: false)
   (0.2ms)  BEGIN
   (0.1ms)  COMMIT
 => true 
 > s
 => #<State id: 6, created_at: "2013-11-04 19:59:25", updated_at: "2013-11-04 19:59:25", wavelet_id: 6> 
 > s.wavelet_id = 500001
 => 500001 
 > s.valid?
  Wavelet Load (0.5ms)  SELECT "wavelets".* FROM "wavelets" WHERE "wavelets"."id" = 500001 LIMIT 1
 => false 
 > s.save(validate: false)
   (0.4ms)  BEGIN
   (2.4ms)  UPDATE "states" SET "wavelet_id" = 500001, "updated_at" = '2013-11-04 20:05:07.388336' WHERE "states"."id" = 6
PG::Error: ERROR:  insert or update on table "states" violates foreign key constraint "states_wavelet_id_fk"
DETAIL:  Key (wavelet_id)=(500001) is not present in table "wavelets".
: UPDATE "states" SET "wavelet_id" = 500001, "updated_at" = '2013-11-04 20:05:07.388336' WHERE "states"."id" = 6
   (0.3ms)  ROLLBACK
ActiveRecord::InvalidForeignKey: PG::Error: ERROR:  insert or update on table "states" violates foreign key constraint "states_wavelet_id_fk"
DETAIL:  Key (wavelet_id)=(500001) is not present in table "wavelets".
: UPDATE "states" SET "wavelet_id" = 500001, "updated_at" = '2013-11-04 20:05:07.388336' WHERE "states"."id" = 6

Hmm, appears that this may be an issue with ActiveRecord. When I removed the foreign key constraints, the behavior was the same. It silently reassigned the old wavelet_id to the State instance. update_column got me the exception that I wanted.

Yeah, there's not much I can do from the perspective of this gem.