require_relative 'helper/copyable_spec_helper' describe 'create_copy!' do before(:each) do undefine_copyable_in CopyableCoin class CopyableCoin < ActiveRecord::Base copyable do disable_all_callbacks_and_observers_except_validate columns({ kind: :copy, year: :copy, }) associations({ }) end end end it 'should exist' do coin = CopyableCoin.create!(kind: 'cent', year: 1909) expect(coin).to respond_to(:create_copy!) end it 'should create a new record' do expect(CopyableCoin.count).to eq(0) coin = CopyableCoin.create!(kind: 'cent', year: 1909) coin.create_copy! expect(CopyableCoin.count).to eq(2) end it 'should return the new record' do expect(CopyableCoin.count).to eq(0) coin = CopyableCoin.create!(kind: 'cent', year: 1909) coin2 = coin.create_copy! expect(coin2).to be_a CopyableCoin end it 'should return the new record having an id' do expect(CopyableCoin.count).to eq(0) coin = CopyableCoin.create!(kind: 'cent', year: 1909) coin2 = coin.create_copy! expect(coin2.id).not_to be_nil end it 'should allow columns to be overridden' do expect(CopyableCoin.count).to eq(0) coin = CopyableCoin.create!(kind: 'cent', year: 1909) coin2 = coin.create_copy!(override: { year: 1959 }) expect(coin2.kind).to eq('cent') expect(coin2.year).to eq(1959) end it 'should allow columns to be overridden using strings as column names' do expect(CopyableCoin.count).to eq(0) coin = CopyableCoin.create!('kind' => 'cent', 'year' => 1909) coin2 = coin.create_copy!(override: { 'year' => 1959 }) expect(coin2.kind).to eq('cent') expect(coin2.year).to eq(1959) end it 'should allow validations to be skipped' do coin = CopyableCoin.create!('kind' => 'cent', 'year' => 1909) expect { coin.create_copy!(override: { 'year' => 2 }) }.to raise_error(ActiveRecord::RecordInvalid) expect { coin.create_copy!(override: { 'year' => 2 }, skip_validations: true) }.to_not raise_error end it 'should skip validations even in associated objects when skip_validations is true' do # set up classes undefine_copyable_in CopyablePet class CopyablePet < ActiveRecord::Base copyable do disable_all_callbacks_and_observers_except_validate columns({ name: :copy, kind: :copy, birth_year: :copy, }) associations({ copyable_toys: :copy, copyable_pet_tag: :do_not_copy, copyable_pet_profile: :do_not_copy, copyable_pet_foods: :do_not_copy, copyable_pet_sitting_patronages: :do_not_copy, }) end end undefine_copyable_in CopyableToy class CopyableToy < ActiveRecord::Base copyable do disable_all_callbacks_and_observers_except_validate columns({ name: :copy, kind: :copy, copyable_pet_id: :copy, }) associations({ }) end end # set up objects fido = CopyablePet.create!( name: 'Fido', kind: 'canine', birth_year: 2005) pillow = CopyableToy.create!( name: 'favorite pillow', kind: 'soft', copyable_pet: fido) # everything should be wonderful expect { fido.create_copy! }.to_not raise_error # now inject some invalid data in an associated object pillow.update_column(:name, 'o') fido.reload # fail because invalid! expect { fido.create_copy! }.to raise_error(ActiveRecord::RecordInvalid) # oh quit complaning and do it anyway! expect { fido.create_copy!(skip_validations: true) }.to_not raise_error end end