Forum: Ruby on Rails before_save returning false does not roll back transaction

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
3f38541776a2513a20ea2f1c2d522cb3?d=identicon&s=25 Perry Smith (pedz)
on 2007-07-07 23:17
I have models with has_many and belongs_to associations. I create a
group of three interconnected records and do a save.  The last record to
be saved does not pass the before_save criteria and so my before_save
function returns false.  I was expecting everything to get rolled back.
But it does not.  Instead, the processing of the third record quits but
the commit happens anyway -- and the save returns true.

I have not pulled this out into a small stand alone example but I am
doing roughly this:

class Relationship < ActiveRecord::Base
  belongs_to :link_type
  belongs_to :parent, :polymorphic => true
  belongs_to :child,  :polymorphic => true

  before_save :banana


  def banana
    errors.add(:parent, "bogus error")"returning false")

class Person < ActiveRecord::Base
  has_many :parents, :as => :parent, :class_name => "Relationship"
  has_many :children, :as => :child, :class_name => "Relationship"

class Company < ActiveRecord::Base
  has_many :parents, :as => :parent, :class_name => "Relationship"
  has_many :children, :as => :child, :class_name => "Relationship"

class PeopleController < ApplicationController
  def create
    @person =[:person])

    # Create optional new Company
    if params[:company][:name] != "" then
      company =
      link_type = LinkType.parent_to_child("Company", "Employee",
      relationship = => link_type)
      @person.children << relationship
      relationship.parent = company
    end"about to save")
    respond_to do |format|
        flash[:notice] = 'Person was successfully created.'
        format.html { redirect_to person_url(@person) }
        format.xml  { head :created, :location => person_url(@person) }
        format.html { render :action => "new" }
        format.xml  { render :xml => @person.errors.to_xml }

The log shows:

  Company Create (0.000210)   INSERT INTO companies ("name",
"created_at") VALUES('c25', '2007-07-07 16:01:07.577598')
  SQL (0.000131)   SELECT currval('companies_id_seq')
before_save is Person
child_id is 23
child_type is Person is Company
parent_id is 26
parent_type is Company
returning false
  SQL (0.001573)  COMMIT
Redirected to http://localhost:3000/rcm/people/23

First Person is saved, then Company is saved, then Relationship is in
the process of being saved but the before_save returns false.  But, I
would expect the whole transaction to be rolled back and the save return
false.  But instead it is committed and the save returns true.  You can
note that we are getting redirected to people/23 not people/new

I'm doing this in before_save because at the time validate is called,
the parent_type is not filled in.  It is the only place where everything
is filled in so I can actually check to make sure everything is right.
The other weird thing is validate for the relationship is being called
twice during this process.  Once early on and again after person and
company has been saved.  The second pass through validate has all the
fields I need but I have not figured out how to determine if this is the
first or second time through validate.

Can someone help?
This topic is locked and can not be replied to.