Perry Smith
2007-Jul-07 21:17 UTC
before_save returning false does not roll back transaction
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 protected def banana errors.add(:parent, "bogus error") logger.info("returning false") false end end class Person < ActiveRecord::Base has_many :parents, :as => :parent, :class_name => "Relationship" has_many :children, :as => :child, :class_name => "Relationship" end class Company < ActiveRecord::Base has_many :parents, :as => :parent, :class_name => "Relationship" has_many :children, :as => :child, :class_name => "Relationship" end class PeopleController < ApplicationController def create @person = Person.new(params[:person]) # Create optional new Company if params[:company][:name] != "" then company Company.find_or_initialize_by_name(params[:company][:name]) link_type = LinkType.parent_to_child("Company", "Employee", "Person") relationship = Relationship.new(:link_type => link_type) @person.children << relationship relationship.parent = company end logger.info("about to save") respond_to do |format| if @person.save flash[:notice] = ''Person was successfully created.'' format.html { redirect_to person_url(@person) } format.xml { head :created, :location => person_url(@person) } else format.html { render :action => "new" } format.xml { render :xml => @person.errors.to_xml } end end end end 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 link_type.child.name is Person child_id is 23 child_type is Person link_type.parent.name 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? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---