Hi everyone, I was surprised to find that when building a collection object, the association callback chain is called. While I''d expect the creation of a record to result in any specified callbacks (i.e., :after_add) being invoked, I wasn''t expecting instantiation to. Was this an intentional decision? If not, I''d be more than happy to supply a patch. Thanks, Brennan --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
I think it makes sense to fire before/after_add callback when the associated object gets build. Doing foo.bars.build() is really ''adding'' the newly build object to the foo.bars collection - so yeah, it was intentional. What''s your use case for delaying the callback chain ? Thanks. On Tue, Aug 18, 2009 at 1:25 AM, Brennan Dunn<me@brennandunn.com> wrote:> Hi everyone, > I was surprised to find that when building a collection object, the > association callback chain is called. While I''d expect the creation of a > record to result in any specified callbacks (i.e., :after_add) being > invoked, I wasn''t expecting instantiation to. Was this an intentional > decision? > If not, I''d be more than happy to supply a patch. > Thanks, > Brennan > > >-- Cheers! - Pratik http://m.onkey.org
There is a related ticket in lighthouse. Looking at it, the consensus seems to be a change in documentation around association callbacks, https://rails.lighthouseapp.com/projects/8994/tickets/2100-patch-change-behaviour-of-associations-after_add-callback -Jatinder On Mon, Aug 17, 2009 at 5:35 PM, Pratik <pratiknaik@gmail.com> wrote:> > I think it makes sense to fire before/after_add callback when the > associated object gets build. Doing foo.bars.build() is really > ''adding'' the newly build object to the foo.bars collection - so yeah, > it was intentional. > > What''s your use case for delaying the callback chain ? > > Thanks. > > On Tue, Aug 18, 2009 at 1:25 AM, Brennan Dunn<me@brennandunn.com> wrote: > > Hi everyone, > > I was surprised to find that when building a collection object, the > > association callback chain is called. While I''d expect the creation of a > > record to result in any specified callbacks (i.e., :after_add) being > > invoked, I wasn''t expecting instantiation to. Was this an intentional > > decision? > > If not, I''d be more than happy to supply a patch. > > Thanks, > > Brennan > > > > > > > > > -- > Cheers! > - Pratik > http://m.onkey.org > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Pratik, In my use case, I''m wanting to fire off an auditing method when a polymorphic object is added to a particular collection. When one of these objects are added to a collection stemming from a Foo object, the auditing needs to take place. But when this object is assigned/created within the scope of a Bar object, which also has_many of these objects, nothing should happen. Granted, I could rig after_save to check to see if its parent is a Foo, and also check to see if the associated_id has changed to simulate what I''m attempting to achieve - but these collection callbacks seemed to make more sense than doing it that way. Even the test suite seems to lend itself to only triggering on physical records: has_many :posts_with_callbacks, :class_name => "Post", :before_add => :log_before_adding, :after_add => :log_after_adding, :before_remove => :log_before_removing, :after_remove => :log_after_removing Logging an object that doesn''t actually exist would quickly cause issues, as it did in my use case, IMO. -Brennan On Mon, Aug 17, 2009 at 8:35 PM, Pratik <pratiknaik@gmail.com> wrote:> > I think it makes sense to fire before/after_add callback when the > associated object gets build. Doing foo.bars.build() is really > ''adding'' the newly build object to the foo.bars collection - so yeah, > it was intentional. > > What''s your use case for delaying the callback chain ? > > Thanks. > > On Tue, Aug 18, 2009 at 1:25 AM, Brennan Dunn<me@brennandunn.com> wrote: > > Hi everyone, > > I was surprised to find that when building a collection object, the > > association callback chain is called. While I''d expect the creation of a > > record to result in any specified callbacks (i.e., :after_add) being > > invoked, I wasn''t expecting instantiation to. Was this an intentional > > decision? > > If not, I''d be more than happy to supply a patch. > > Thanks, > > Brennan > > > > > > > > > -- > Cheers! > - Pratik > http://m.onkey.org > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
I think this is a sign that we''re lacking some callbacks. My ideal solution would be to get rid of before/after_add callbacks and replace them with a super set - something like around_add and arround_commit callbacks ( much like controller''s around filters ) - where ''commit'' is the process of saving records to the db. It''d be good to get more feedback from people who''re actively using these callbacks. On Tue, Aug 18, 2009 at 1:46 AM, Brennan Dunn<me@brennandunn.com> wrote:> Pratik, > In my use case, I''m wanting to fire off an auditing method when a > polymorphic object is added to a particular collection. When one of these > objects are added to a collection stemming from a Foo object, the auditing > needs to take place. But when this object is assigned/created within the > scope of a Bar object, which also has_many of these objects, nothing should > happen. > Granted, I could rig after_save to check to see if its parent is a Foo, and > also check to see if the associated_id has changed to simulate what I''m > attempting to achieve - but these collection callbacks seemed to make more > sense than doing it that way. > Even the test suite seems to lend itself to only triggering on physical > records: > has_many :posts_with_callbacks, :class_name => "Post", :before_add => > :log_before_adding, > :after_add => :log_after_adding, > :before_remove => :log_before_removing, > :after_remove => :log_after_removing > Logging an object that doesn''t actually exist would quickly cause issues, as > it did in my use case, IMO. > -Brennan > > On Mon, Aug 17, 2009 at 8:35 PM, Pratik <pratiknaik@gmail.com> wrote: >> >> I think it makes sense to fire before/after_add callback when the >> associated object gets build. Doing foo.bars.build() is really >> ''adding'' the newly build object to the foo.bars collection - so yeah, >> it was intentional. >> >> What''s your use case for delaying the callback chain ? >> >> Thanks. >> >> On Tue, Aug 18, 2009 at 1:25 AM, Brennan Dunn<me@brennandunn.com> wrote: >> > Hi everyone, >> > I was surprised to find that when building a collection object, the >> > association callback chain is called. While I''d expect the creation of a >> > record to result in any specified callbacks (i.e., :after_add) being >> > invoked, I wasn''t expecting instantiation to. Was this an intentional >> > decision? >> > If not, I''d be more than happy to supply a patch. >> > Thanks, >> > Brennan >> > > >> > >> >> >> >> -- >> Cheers! >> - Pratik >> http://m.onkey.org >> >> > > > > >-- Cheers! - Pratik http://m.onkey.org
Pratik, That sounds like a great solution to the tough issue of ordering semantics. As it stands today, I''m not sure I could explain how insert/append+before/after/around work together to express precedence. -Chris On Aug 18, 10:26 am, Pratik <pratikn...@gmail.com> wrote:> I think this is a sign that we''re lacking some callbacks. My ideal > solution would be to get rid of before/after_add callbacks and replace > them with a super set - something like around_add and arround_commit > callbacks ( much like controller''s around filters ) - where ''commit'' > is the process of saving records to the db. It''d be good to get more > feedback from people who''re actively using these callbacks. > > > > On Tue, Aug 18, 2009 at 1:46 AM, Brennan Dunn<m...@brennandunn.com> wrote: > > Pratik, > > In my use case, I''m wanting to fire off an auditing method when a > > polymorphic object is added to a particular collection. When one of these > > objects are added to a collection stemming from a Foo object, the auditing > > needs to take place. But when this object is assigned/created within the > > scope of a Bar object, which also has_many of these objects, nothing should > > happen. > > Granted, I could rig after_save to check to see if its parent is a Foo, and > > also check to see if the associated_id has changed to simulate what I''m > > attempting to achieve - but these collection callbacks seemed to make more > > sense than doing it that way. > > Even the test suite seems to lend itself to only triggering on physical > > records: > > has_many :posts_with_callbacks, :class_name => "Post", :before_add => > > :log_before_adding, > > :after_add => :log_after_adding, > > :before_remove => :log_before_removing, > > :after_remove => :log_after_removing > > Logging an object that doesn''t actually exist would quickly cause issues, as > > it did in my use case, IMO. > > -Brennan > > > On Mon, Aug 17, 2009 at 8:35 PM, Pratik <pratikn...@gmail.com> wrote: > > >> I think it makes sense to fire before/after_add callback when the > >> associated object gets build. Doing foo.bars.build() is really > >> ''adding'' the newly build object to the foo.bars collection - so yeah, > >> it was intentional. > > >> What''s your use case for delaying the callback chain ? > > >> Thanks. > > >> On Tue, Aug 18, 2009 at 1:25 AM, Brennan Dunn<m...@brennandunn.com> wrote: > >> > Hi everyone, > >> > I was surprised to find that when building a collection object, the > >> > association callback chain is called. While I''d expect the creation of a > >> > record to result in any specified callbacks (i.e., :after_add) being > >> > invoked, I wasn''t expecting instantiation to. Was this an intentional > >> > decision? > >> > If not, I''d be more than happy to supply a patch. > >> > Thanks, > >> > Brennan > > >> -- > >> Cheers! > >> - Pratik > >>http://m.onkey.org > > -- > Cheers! > - Pratikhttp://m.onkey.org
After grappling with this for a while, here are my thoughts on association callbacks: First, I now completely understand why :after_add cares nothing for persistence, and is solely a callback for pushing/popping an item from an association collection. At the database level, @category.products.create is going to give you the same results as @product.category = @category. So essentially, if you put a product within a category the latter way, and have some sort of :after_add callback based on the association collection, that callback won''t be fired. It would almost be better to have a callback at the belongs_to association definition if the goal is to have a callback for changes of association. That being said, what strikes me about :after_add as being odd is that it seems to be the only AR callback - outside of the validation callbacks and maybe after_initialize - that has nothing to do with persistence. And since ActiveRecord by definition is a means of mapping objects to persisted records, I think I was expecting :after_add to have something to do with saving. With so much happening with ActiveModel (which doesn''t care about persistence), and ActiveRecord (= persistence) adopting callbacks from AM, I think it''s good thing that there''s an active discussion on callbacks happening. -Brennan On Wed, Aug 19, 2009 at 9:17 AM, Chris <cch1@hapgoods.com> wrote:> > Pratik, > That sounds like a great solution to the tough issue of ordering > semantics. As it stands today, I''m not sure I could explain how > insert/append+before/after/around work together to express precedence. > > -Chris > > On Aug 18, 10:26 am, Pratik <pratikn...@gmail.com> wrote: > > I think this is a sign that we''re lacking some callbacks. My ideal > > solution would be to get rid of before/after_add callbacks and replace > > them with a super set - something like around_add and arround_commit > > callbacks ( much like controller''s around filters ) - where ''commit'' > > is the process of saving records to the db. It''d be good to get more > > feedback from people who''re actively using these callbacks. > > > > > > > > On Tue, Aug 18, 2009 at 1:46 AM, Brennan Dunn<m...@brennandunn.com> > wrote: > > > Pratik, > > > In my use case, I''m wanting to fire off an auditing method when a > > > polymorphic object is added to a particular collection. When one of > these > > > objects are added to a collection stemming from a Foo object, the > auditing > > > needs to take place. But when this object is assigned/created within > the > > > scope of a Bar object, which also has_many of these objects, nothing > should > > > happen. > > > Granted, I could rig after_save to check to see if its parent is a Foo, > and > > > also check to see if the associated_id has changed to simulate what I''m > > > attempting to achieve - but these collection callbacks seemed to make > more > > > sense than doing it that way. > > > Even the test suite seems to lend itself to only triggering on physical > > > records: > > > has_many :posts_with_callbacks, :class_name => "Post", :before_add => > > > :log_before_adding, > > > :after_add => :log_after_adding, > > > :before_remove => :log_before_removing, > > > :after_remove => :log_after_removing > > > Logging an object that doesn''t actually exist would quickly cause > issues, as > > > it did in my use case, IMO. > > > -Brennan > > > > > On Mon, Aug 17, 2009 at 8:35 PM, Pratik <pratikn...@gmail.com> wrote: > > > > >> I think it makes sense to fire before/after_add callback when the > > >> associated object gets build. Doing foo.bars.build() is really > > >> ''adding'' the newly build object to the foo.bars collection - so yeah, > > >> it was intentional. > > > > >> What''s your use case for delaying the callback chain ? > > > > >> Thanks. > > > > >> On Tue, Aug 18, 2009 at 1:25 AM, Brennan Dunn<m...@brennandunn.com> > wrote: > > >> > Hi everyone, > > >> > I was surprised to find that when building a collection object, the > > >> > association callback chain is called. While I''d expect the creation > of a > > >> > record to result in any specified callbacks (i.e., :after_add) being > > >> > invoked, I wasn''t expecting instantiation to. Was this an > intentional > > >> > decision? > > >> > If not, I''d be more than happy to supply a patch. > > >> > Thanks, > > >> > Brennan > > > > >> -- > > >> Cheers! > > >> - Pratik > > >>http://m.onkey.org > > > > -- > > Cheers! > > - Pratikhttp://m.onkey.org > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---