Hey, I''ve got a following scenario: Reply has_many :venues, :through => :venue_suggestions. When user answers to a question he can add venues to it as suggestions. The problem is that these venues (actually their IDs) are added to the reply form, before the reply is created. Wnever a venue is added or removed from a reply, I''d like to call a function that updates a score of the added venue. And here''s the problem: - I can''t use after_add/after_remove callbacks in Reply model, because after_add is called before the reply is actually saved and the associations are not built yet - I can''t use after_create/after_destroy callbacks in VenueSuggestion, because after_destroy callback is never called. Looking at the code in Rails 2.3.8 branch it seems that doing something like this: reply.venue_ids = [] calls delete_all, which doesn''t call any callbacks. In Rails 3 it works in the same way. So I guess I''m left with after_create and after_remove callbacks in 2 models... Does anyone have any idea how these callbacks should actually work in has_many :through association? -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Veera Sundaravel
2010-Jun-22 07:29 UTC
Re: Problem with callbacks and has_many :through association
Hi Szymon, you can use after_create and after_destroy callback method in venue_suggestions model. So when ever you are assigning a new venue to a reply it will create a record in venue_suggestions table and call the after_create method. But the issue with after_destroy is: if you are trying to remove venues from the reply means it will not fire the after_destroy call_back. So better some thing like below: r = Reply.first r.venues << Venue.first r.venues << Venue.last #So it will fire the after_create call back. #But if you want to remove a particular venue from the reply means, go some thing like this r.venue_suggestions.find_by_venue_id(1).destroy or r.reply_venues.find_all_by_venue_id(1).each{|x| x.destroy} but r.venues = [] wont call the after_destroy, cos these type of assignment will fire the delete_all method against venue_suggestions table where delete_all wont run any callbacks. Hope this will help you, if you need further assistance on this, let me know. Szymon Nowak wrote:> Hey, > > I''ve got a following scenario: Reply has_many :venues, :through > => :venue_suggestions. When user answers to a question he can add > venues to it as suggestions. The problem is that these venues > (actually their IDs) are added to the reply form, before the reply is > created. Wnever a venue is added or removed from a reply, I''d like to > call a function that updates a score of the added venue. > > And here''s the problem: > > - I can''t use after_add/after_remove callbacks in Reply model, because > after_add is called before the reply is actually saved and the > associations are not built yet > > - I can''t use after_create/after_destroy callbacks in VenueSuggestion, > because after_destroy callback is never called. Looking at the code in > Rails 2.3.8 branch it seems that doing something like this: > reply.venue_ids = [] > calls delete_all, which doesn''t call any callbacks. In Rails 3 it > works in the same way. > > So I guess I''m left with after_create and after_remove callbacks in 2 > models... Does anyone have any idea how these callbacks should > actually work in has_many :through association?-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Thanks for the reply! Basically the problem was that we were using a form were we had dynamically added/removed hidden fields with venue IDs - they were later passed as an array (:params => {:venue_ids => [something]}), that''s why I was mainly interested in reply#venue_ids= assignment. I solved it with combination of after_create and after_remove callbacks, but the main point is that it''s not very well documented and it''s actually impossible to get desired behavior in case of habtm association where only after_add/remove callbacks are available. I''m not sure if the behavior of these callbacks is intended and it''s simply an issue with properly documenting these quirks or the behavior itself should be fixed. On Jun 22, 9:29 am, Veera Sundaravel <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> Hi Szymon, > > you can use after_create and after_destroy callback method in > venue_suggestions model. > > So when ever you are assigning a new venue to a reply it will create a > record in venue_suggestions table and call the after_create method. > > But the issue with after_destroy is: > > if you are trying to remove venues from the reply means it will not fire > the after_destroy call_back. So better some thing like below: > > r = Reply.first > r.venues << Venue.first > r.venues << Venue.last > > #So it will fire the after_create call back. > > #But if you want to remove a particular venue from the reply means, go > some thing like this > > r.venue_suggestions.find_by_venue_id(1).destroy > or > r.reply_venues.find_all_by_venue_id(1).each{|x| x.destroy} > > but r.venues = [] wont call the after_destroy, cos these type of > assignment will fire the delete_all method against venue_suggestions > table where delete_all wont run any callbacks. > > Hope this will help you, if you need further assistance on this, let me > know. > > > > > > Szymon Nowak wrote: > > Hey, > > > I''ve got a following scenario: Reply has_many :venues, :through > > => :venue_suggestions. When user answers to a question he can add > > venues to it as suggestions. The problem is that these venues > > (actually their IDs) are added to the reply form, before the reply is > > created. Wnever a venue is added or removed from a reply, I''d like to > > call a function that updates a score of the added venue. > > > And here''s the problem: > > > - I can''t use after_add/after_remove callbacks in Reply model, because > > after_add is called before the reply is actually saved and the > > associations are not built yet > > > - I can''t use after_create/after_destroy callbacks in VenueSuggestion, > > because after_destroy callback is never called. Looking at the code in > > Rails 2.3.8 branch it seems that doing something like this: > > reply.venue_ids = [] > > calls delete_all, which doesn''t call any callbacks. In Rails 3 it > > works in the same way. > > > So I guess I''m left with after_create and after_remove callbacks in 2 > > models... Does anyone have any idea how these callbacks should > > actually work in has_many :through association? > > -- > Posted viahttp://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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.