The models: class User has_many :institution_memberships belongs_to :account after_create :set_default_membership def set_default_membership if institution_memberships.empty? institution_memberships.create(default_data_from_account) end end end class InstitutionMembership validates_uniqueness_of :user_id, :scope => :institution_id end Controller: def create @account = Account.new @account.transaction do @user = User.new(params[:user]) @institution = Institution.new(:name => @account.name) @user.account = @account @institution.account = @account @institution_membership = InstitutionMembership.new( :institution => @institution, :user => @user ) if @user.save && @institution.save && @institution_membership.save end end end To put this into context. A user can belong to one or many institutions. The relationship is managed through :institution_memberships. A user can only have one membership per institution, hence the validates_uniqueness_of :user_id, :scope => :institution_id There is a lot more code happening around all of this than i''ve shown, but the main problem is that basically two memberships are being created for a user with the same institution. The validate is not working. The after_create callback is creating an object successfully, and the standard save in the controller is working. My guess is it has something to do with the timing of things and when they''re actually written to the database, but i don''t know that process well enough to pinpoint the exact cause. Obviously there is no need to create a membership object in the controller, but the code had been that way for a long time without a problem. Nobody noticed it until suddenly the bad data started showing up. I''m more curious as to why the validation goes through. What''s the community think? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/a290ade05152fbdef11416ed80fab3b3%40ruby-forum.com. For more options, visit https://groups.google.com/groups/opt_out.
On Thursday, 1 August 2013 10:56:06 UTC-4, Ruby-Forum.com User wrote:> > The models: > > class User > has_many :institution_memberships > belongs_to :account > > after_create :set_default_membership > > def set_default_membership > if institution_memberships.empty? > institution_memberships.create(default_data_from_account) > end > end > end > > class InstitutionMembership > validates_uniqueness_of :user_id, :scope => :institution_id > end > > Controller: > > def create > @account = Account.new > @account.transaction do > @user = User.new(params[:user]) > @institution = Institution.new(:name => @account.name) > @user.account = @account > @institution.account = @account > @institution_membership = InstitutionMembership.new( > :institution => @institution, > :user => @user > ) > > if @user.save && @institution.save && > @institution_membership.save > > end > end > end > > To put this into context. A user can belong to one or many institutions. > The relationship is managed through :institution_memberships. A user can > only have one membership per institution, hence the > validates_uniqueness_of :user_id, :scope => :institution_id > > There is a lot more code happening around all of this than i''ve shown, > but the main problem is that basically two memberships are being created > for a user with the same institution. The validate is not working. The > after_create callback is creating an object successfully, and the > standard save in the controller is working. > > My guess is it has something to do with the timing of things and when > they''re actually written to the database, but i don''t know that process > well enough to pinpoint the exact cause. Obviously there is no need to > create a membership object in the controller, but the code had been that > way for a long time without a problem. Nobody noticed it until suddenly > the bad data started showing up. I''m more curious as to why the > validation goes through. > > What''s the community think? > >Can you post a log of the SQL that gets executed during the transaction? I''m curious about what the validates_uniqueness_of is looking up, if anything. --Matt Jones -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/f3b6e39a-ec5d-47cf-ba8e-805fd0987b0b%40googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Matt Jones wrote in post #1117517:> On Thursday, 1 August 2013 10:56:06 UTC-4, Ruby-Forum.com User wrote: >> if institution_memberships.empty? >> >> ) >> only have one membership per institution, hence the >> well enough to pinpoint the exact cause. Obviously there is no need to >> create a membership object in the controller, but the code had been that >> way for a long time without a problem. Nobody noticed it until suddenly >> the bad data started showing up. I''m more curious as to why the >> validation goes through. >> >> What''s the community think? >> >> > Can you post a log of the SQL that gets executed during the transaction? > I''m curious about what the validates_uniqueness_of is looking up, if > anything. > > --Matt JonesI attached a part of the log from my functional testing. What i assume to be the validation check SELECT statement does not have a user_id yet. However the DB INSERT occurring right after, does have the user_id. Very puzzling. FYI I''m on Rails 2.3.15 Attachments: http://www.ruby-forum.com/attachment/8650/query_log.txt -- 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 unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/6980a8a3360434ff72301fbf698f61c2%40ruby-forum.com. For more options, visit https://groups.google.com/groups/opt_out.
selva4210-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2013-Aug-06 09:20 UTC
Re: Re: Validations not working on complex DB transaction
Hi, The @user object is getting saved first. That time, there is no instuition membership attached to it. So one is getting created. Then when you save the instuition membership again inside the controller it also gets saved. Is this clear? On Sat, Aug 3, 2013 at 2:00 AM, masta Blasta <lists-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> Matt Jones wrote in post #1117517: >> On Thursday, 1 August 2013 10:56:06 UTC-4, Ruby-Forum.com User wrote: >>> if institution_memberships.empty? >>> >>> ) >>> only have one membership per institution, hence the >>> well enough to pinpoint the exact cause. Obviously there is no need to >>> create a membership object in the controller, but the code had been that >>> way for a long time without a problem. Nobody noticed it until suddenly >>> the bad data started showing up. I''m more curious as to why the >>> validation goes through. >>> >>> What''s the community think? >>> >>> >> Can you post a log of the SQL that gets executed during the transaction? >> I''m curious about what the validates_uniqueness_of is looking up, if >> anything. >> >> --Matt Jones > > > I attached a part of the log from my functional testing. What i assume > to be the validation check SELECT statement does not have a user_id yet. > However the DB INSERT occurring right after, does have the user_id. > > Very puzzling. FYI I''m on Rails 2.3.15 > > Attachments: > http://www.ruby-forum.com/attachment/8650/query_log.txt > > > -- > 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 unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/6980a8a3360434ff72301fbf698f61c2%40ruby-forum.com. > For more options, visit https://groups.google.com/groups/opt_out. > >-- Azhagu Selvan http://tamizhgeek.in -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/CABX9Rmz0w5kTE%3Ds2A3tY%2B%2BtdzDKcPpXUL-j4qw-GyCh-Bko3Jg%40mail.gmail.com. For more options, visit https://groups.google.com/groups/opt_out.
Carlos Figueiredo
2013-Aug-06 11:20 UTC
Re: Re: Validations not working on complex DB transaction
Yeah, It''s exactly that... you are creating a user before the Institution... But I your controller isn''t searching for some Institution while creating the User... I just see your controller creating an Institution... doesn''t matter if already exists... *Carlos Figueiredo* On Tue, Aug 6, 2013 at 6:20 AM, selva4210-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org <selva4210-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote:> Hi, > > The @user object is getting saved first. That time, there is no > instuition membership attached to it. So one is getting created. Then > when you save the instuition membership again inside the controller it > also gets saved. > > Is this clear? > > On Sat, Aug 3, 2013 at 2:00 AM, masta Blasta <lists-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote: > > Matt Jones wrote in post #1117517: > >> On Thursday, 1 August 2013 10:56:06 UTC-4, Ruby-Forum.com User wrote: > >>> if institution_memberships.empty? > >>> > >>> ) > >>> only have one membership per institution, hence the > >>> well enough to pinpoint the exact cause. Obviously there is no need to > >>> create a membership object in the controller, but the code had been > that > >>> way for a long time without a problem. Nobody noticed it until suddenly > >>> the bad data started showing up. I''m more curious as to why the > >>> validation goes through. > >>> > >>> What''s the community think? > >>> > >>> > >> Can you post a log of the SQL that gets executed during the transaction? > >> I''m curious about what the validates_uniqueness_of is looking up, if > >> anything. > >> > >> --Matt Jones > > > > > > I attached a part of the log from my functional testing. What i assume > > to be the validation check SELECT statement does not have a user_id yet. > > However the DB INSERT occurring right after, does have the user_id. > > > > Very puzzling. FYI I''m on Rails 2.3.15 > > > > Attachments: > > http://www.ruby-forum.com/attachment/8650/query_log.txt > > > > > > -- > > 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 unsubscribe from this group and stop receiving emails from it, send > an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > > To view this discussion on the web visit > https://groups.google.com/d/msgid/rubyonrails-talk/6980a8a3360434ff72301fbf698f61c2%40ruby-forum.com > . > > For more options, visit https://groups.google.com/groups/opt_out. > > > > > > > > -- > Azhagu Selvan > > http://tamizhgeek.in > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Talk" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To view this discussion on the web visit > https://groups.google.com/d/msgid/rubyonrails-talk/CABX9Rmz0w5kTE%3Ds2A3tY%2B%2BtdzDKcPpXUL-j4qw-GyCh-Bko3Jg%40mail.gmail.com > . > For more options, visit https://groups.google.com/groups/opt_out. > > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/CANPOtXvyDqz_iE_C6A8LE0r58CeNPnC%3DvxGvVB__%3D39%3D_xDG5g%40mail.gmail.com. For more options, visit https://groups.google.com/groups/opt_out.
masta Blasta
2013-Aug-06 14:13 UTC
Re: Re: Validations not working on complex DB transaction
selva4210-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote in post #1117870:> Hi, > > The @user object is getting saved first. That time, there is no > instuition membership attached to it. So one is getting created. Then > when you save the instuition membership again inside the controller it > also gets saved. > > Is this clear?You just restated what i had initially written. The "problem" is something to do with how rails connects newly initialized objects that are in memory but not yet in the database. We have built two objects like this u = User.new im = InstitutionMembership.new :user => u At that point the u (User) object doesn''t know anything about the im object. Saving the u object does not trigger an autosave on the association, and the create callback creates a new membership. That''s somewhat expected. The odd issues appear after - u = User.new im = InstitutionMembership.new :user => u u.save im.save ''im'' is aware of the user object, however it is not able to validate against it. When it attempts to validate, the user_id==NULL. At the very next log entry though, it saves itself with the correct user_id. So somewhere between the validate callbacks, and the create and commit callbacks, the ''im'' object refreshed the user object and retrieved the user_id. Also the new_record? flag on ''im'' is still set, so a new row is created. One of the better solutions was actually to do: u = User.new im = u.institution_memberships.build This is able to properly connect the objects in memory, and the process works smoothly. The association is autosaved on u.save -- 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 unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/fc9852aaa5e23f13c8185ac013988a08%40ruby-forum.com. For more options, visit https://groups.google.com/groups/opt_out.
Rob Biedenharn
2013-Aug-06 14:44 UTC
Re: Re: Re: Validations not working on complex DB transaction
On 2013-Aug-6, at 10:13 , masta Blasta wrote:> selva4210-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote in post #1117870: >> Hi, >> >> The @user object is getting saved first. That time, there is no >> instuition membership attached to it. So one is getting created. Then >> when you save the instuition membership again inside the controller it >> also gets saved. >> >> Is this clear? > > You just restated what i had initially written. > > > The "problem" is something to do with how rails connects newly > initialized objects that are in memory but not yet in the database. > > We have built two objects like this > u = User.new > im = InstitutionMembership.new :user => u > > At that point the u (User) object doesn''t know anything about the im > object. Saving the u object does not trigger an autosave on the > association, and the create callback creates a new membership. That''s > somewhat expected.So tell ActiveRecord that you *want* the autosave: class User < ActiveRecord::Base belongs_to :account has_many :institution_memberships, :autosave => :always has_many :institutions, :through => :institution_memberships after_create :set_default_membership def set_default_membership if institution_memberships(true).blank? institution_memberships.create(default_data_from_account) end end end class InstitutionMembership < ActiveRecord::Base belongs_to :user belongs_to :institution validates_uniqueness_of :user_id, :scope => :institution_id end Note the argument to ''institution_memberships(true)'' which causes the memberships to be reloaded from the database.> > The odd issues appear after - > u = User.new > im = InstitutionMembership.new :user => u > u.save > im.saveI assume that you''ve simplified this so that the account_id or however the default_data_from_account manages to find the institution_id is missing. u = User.new u.institutions << Institution.find(somehow) or u = User.new u.institution_memberships << InstitutionMembership.new(:institution_id => from_a_parameter_perhaps) and then the u.save should do the right thing. -Rob> > ''im'' is aware of the user object, however it is not able to validate > against it. When it attempts to validate, the user_id==NULL. At the very > next log entry though, it saves itself with the correct user_id. So > somewhere between the validate callbacks, and the create and commit > callbacks, the ''im'' object refreshed the user object and retrieved the > user_id. Also the new_record? flag on ''im'' is still set, so a new row is > created. > > One of the better solutions was actually to do: > u = User.new > im = u.institution_memberships.build > > This is able to properly connect the objects in memory, and the process > works smoothly. The association is autosaved on u.save > > -- > 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 unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/fc9852aaa5e23f13c8185ac013988a08%40ruby-forum.com. > For more options, visit https://groups.google.com/groups/opt_out. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/96105FD7-E973-459F-AF68-27EF426A35C4%40agileconsultingllc.com. For more options, visit https://groups.google.com/groups/opt_out.
Rob Biedenharn
2013-Aug-06 14:46 UTC
Re: Re: Re: Validations not working on complex DB transaction
On 2013-Aug-6, at 10:13 , masta Blasta wrote:> selva4210-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote in post #1117870: >> Hi, >> >> The @user object is getting saved first. That time, there is no >> instuition membership attached to it. So one is getting created. Then >> when you save the instuition membership again inside the controller it >> also gets saved. >> >> Is this clear? > > You just restated what i had initially written. > > > The "problem" is something to do with how rails connects newly > initialized objects that are in memory but not yet in the database. > > We have built two objects like this > u = User.new > im = InstitutionMembership.new :user => u > > At that point the u (User) object doesn''t know anything about the im > object. Saving the u object does not trigger an autosave on the > association, and the create callback creates a new membership. That''s > somewhat expected.So tell ActiveRecord that you *want* the autosave: class User < ActiveRecord::Base belongs_to :account has_many :institution_memberships, :autosave => :always has_many :institutions, :through => :institution_memberships after_create :set_default_membership def set_default_membership if institution_memberships(true).blank? institution_memberships.create(default_data_from_account) end end end class InstitutionMembership < ActiveRecord::Base belongs_to :user belongs_to :institution validates_uniqueness_of :user_id, :scope => :institution_id end Note the argument to ''institution_memberships(true)'' which causes the memberships to be reloaded from the database and the :autosave option added to the has_many.> > The odd issues appear after - > u = User.new > im = InstitutionMembership.new :user => u > u.save > im.saveI assume that you''ve simplified this so that the account_id or however the default_data_from_account manages to find the institution_id is missing. u = User.new u.institutions << Institution.find(somehow) or u = User.new u.institution_memberships << InstitutionMembership.new(:institution_id => from_a_parameter_perhaps) and then the u.save should do the right thing. -Rob> > ''im'' is aware of the user object, however it is not able to validate > against it. When it attempts to validate, the user_id==NULL. At the very > next log entry though, it saves itself with the correct user_id. So > somewhere between the validate callbacks, and the create and commit > callbacks, the ''im'' object refreshed the user object and retrieved the > user_id. Also the new_record? flag on ''im'' is still set, so a new row is > created. > > One of the better solutions was actually to do: > u = User.new > im = u.institution_memberships.build > > This is able to properly connect the objects in memory, and the process > works smoothly. The association is autosaved on u.save > > -- > 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 unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/fc9852aaa5e23f13c8185ac013988a08%40ruby-forum.com. > For more options, visit https://groups.google.com/groups/opt_out. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/27496B38-FDB8-4F74-A6BB-73888B537DA3%40gmail.com. For more options, visit https://groups.google.com/groups/opt_out.