Rails ActiveRecord::RecordInvalid exception not raised in after_create of association

Viewed 2081

I have 3 very simple models

class Receipt < ActiveRecord::Base
  has_many :receipt_items
end

class ReceiptItem < ActiveRecord::Base
  after_create :create_transaction
  belongs_to :receipt
private
  def create_transaction
    Transaction.new.save!
  end
end

class Transaction < ActiveRecord::Base
  validates :transacted_at, :presence => true
end

So every time a new ReceiptItem is created, it triggers the after_create callback to create a new Transaction object using save!. But because Transaction requires that the column transacted_at to be present, Transaction.new.save! should raise an ActiveRecord::RecordInvalid every time, I assumed.

So then I created 3 tests:

test "creating an invalid transaction" do
    assert_raises ActiveRecord::RecordInvalid do
        Transaction.new.save!
    end
end

test "creating invalid transaction in after_create" do
    assert_raises ActiveRecord::RecordInvalid do
        ReceiptItem.new.save!
    end
end

test "creating invalid transaction in after_create of associated model" do
    assert_raises ActiveRecord::RecordInvalid do
        r = Receipt.new
        i = r.receipt_items.new
        r.save!
    end
end

The first two tests passed as expected. The third test, however, failed because the exception was never raised. As a matter of fact, if I add the following lines after the 'r.save!' line:

r.reload
p r.inspect
p r.receipt_items.inspect

I could see that the Receipt and the ReceiptItem have been created successfully.

Furthermore, if I replaced

assert_raises ActiveRecord::RecordInvalid do

with

assert_difference "Transaction.count", +1 do

I confirmed that the Receipt and the ReceiptItems were created but the Transaction wasn't. That means the creation of the Transaction failed, but was silently ignored, even though I used 'save!' as opposed to just 'save'.

Does anyone know if this is the intended behaviour, or is this actually a bug in Rails?

(Tried this in Rails 4.0.13 and 4.2.0)

Update

I've filed a bug report here: https://github.com/rails/rails/issues/24301

1 Answers
Related