Scott
2007-Oct-25 22:41 UTC
How Do I: Avoid an Infinite Loop using Before Save and After Save?
I have an entity that looks something like this: journal author_first_name author_last_name journal_name journal_email_address where journal_name = author_first_name + '' '' + author_last_name journal_email_address = journal_name + ''-'' id I had journal_name and journal_email_address implemented as attributes on the Journal model, but the time came along where, for various reasons, it has become valuable to also store that information in the database. So, what I thought I''d do, in app/models/journal.rb: def make_journal_name self.journal_name = self.author_first_name + '' '' + self.author_last_name end def make_inbound_email self.inbound_email = self.journal_name.gsub(/[^a-zA-Z0-9]/, '''') + ''-'' + self.id.to_s end def before_save make_journal_name make_inbound_email end which works fine in the case of an update of an existing record. However, it does not work in the case of a creation of a new record because before saving self.id does not exist. The result was my e- mail addresses are looking like "SallyJones-" as opposed to "SallyJones-64". Okay, I thought, "since I need an ID to work with I''ll move this to after_save," like so: def after_save make_journal_name make_inbound_email self.save end but that creates an infinite loop. At this point, I''m sort of stumped for what to do...thoughts on how I could make this work? --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Lionel Bouton
2007-Oct-25 23:10 UTC
Re: How Do I: Avoid an Infinite Loop using Before Save and After Save?
Scott wrote:> I have an entity that looks something like this: > > journal > author_first_name > author_last_name > journal_name > journal_email_address > > where > journal_name = author_first_name + '' '' + author_last_name > journal_email_address = journal_name + ''-'' id > > I had journal_name and journal_email_address implemented as attributes > on the Journal model, but the time came along where, for various > reasons, it has become valuable to also store that information in the > database. So, what I thought I''d do, in app/models/journal.rb: > > def make_journal_name > self.journal_name = self.author_first_name + '' '' + > self.author_last_name > end > > def make_inbound_email > self.inbound_email = self.journal_name.gsub(/[^a-zA-Z0-9]/, '''') + > ''-'' + self.id.to_s > end > > def before_save > make_journal_name > make_inbound_email > end > > which works fine in the case of an update of an existing record. > However, it does not work in the case of a creation of a new record > because before saving self.id does not exist. The result was my e- > mail addresses are looking like "SallyJones-" as opposed to > "SallyJones-64". > > Okay, I thought, "since I need an ID to work with I''ll move this to > after_save," like so: > > def after_save > make_journal_name > make_inbound_email > self.save > end > > but that creates an infinite loop. > > At this point, I''m sort of stumped for what to do...thoughts on how I > could make this work? > >I don''t really understand why you need these columns as they could easily be computed on the fly by the model with simple methods. If you really, really want to do this, you can update the record with raw SQL instead of using self.save. From memory: execute("UPDATE #{table_name} SET inbound_email ''#{make_inbound_email}'', journal_name = ''#{make_journal_name}'' WHERE id = ''#{id}''") It would work with your current make_* methods as they return the value they set in the model which have the added benefit that your model is in sync with the DB. But I''d really like to know why you have to break database basic normalization rules (don''t put twice the same data in your database to avoid inconsistencies, should be part of the "first normal form" if my old DB courses serve me right). Lionel --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Scott
2007-Oct-25 23:21 UTC
Re: How Do I: Avoid an Infinite Loop using Before Save and After Save?
Thank you for your response. Actually, that doesn''t quite solve my problem because my original intention of using before_save worked for updates, and the SQL above is an UPDATE. The real problem is when I''m creating a new object, i.e. doing an INSERT. I could change the SQL to an INSERT, but I''d really have to make sure that didn''t screw anything up. As far as the need: I do lookups based on those attributes, the email address especially, and it will speed things up (and eliminate errors) if I can do an lookup on an indexed column as opposed to parsing the string to figure out what to look up. Another option is to call make_* methods from the #create and #update methods in my controllers, although that seems like an odd place for them. Scott --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Lionel Bouton
2007-Oct-25 23:39 UTC
Re: How Do I: Avoid an Infinite Loop using Before Save and After Save?
Scott wrote:> Thank you for your response. > > Actually, that doesn''t quite solve my problem because my original > intention of using before_save worked for updates, and the SQL above > is an UPDATE.Right, the insert is already done at this point. So the only task left is to fill the missing columns which only an update can do...> The real problem is when I''m creating a new object, > i.e. doing an INSERT. I could change the SQL to an INSERT, but I''d > really have to make sure that didn''t screw anything up. >It would because the INSERT is already done: you''ll get an SQL exception.> As far as the need: I do lookups based on those attributes, the email > address especially, and it will speed things up (and eliminate errors) > if I can do an lookup on an indexed column as opposed to parsing the > string to figure out what to look up. >Maybe, depends on the details, if you can pre-process the query to infer a query on the components, it should be the fastest way (query on smaller columns are always faster). If you can''t, then... you can''t :-) Depending on your database on you can even index expressions, so you could make find_sql with conditions that look like "(col1 || '' '' || col2) LIKE ''escaped_querystring''" and have the database index concat(col1, '' '', col2) for you (PostgreSQL supports this since ages ago). This should be the more robust and fastest way. Lionel --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Oct-25 23:40 UTC
Re: How Do I: Avoid an Infinite Loop using Before Save and After Save?
Scott wrote:> > def after_save > make_journal_name > make_inbound_email > self.save > end > > but that creates an infinite loop.Instead of "save" use "update_without_callbacks" -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Scott
2007-Oct-26 00:58 UTC
Re: How Do I: Avoid an Infinite Loop using Before Save and After Save?
Mark...update_without_callbacks does exactly what I needed. Thanks! However, I can''t find it mentioned anywhere in the documentation. I grepped the code and found that it''s set for #:nodoc. a) how could i have known this exists without knowing every line of code? b) how did you know this exists? c) why is this method, and others, not included in the docs? someone had to choose to add #:nodoc to the code...why did they choose to do that? On Oct 25, 4:40 pm, Mark Reginald James <m...-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:> Scott wrote: > > > def after_save > > make_journal_name > > make_inbound_email > > self.save > > end > > > but that creates an infinite loop. > > Instead of "save" use "update_without_callbacks" > > -- > We develop, watch us RoR, in numbers too big to ignore.--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Oct-28 11:51 UTC
Re: How Do I: Avoid an Infinite Loop using Before Save and After Save?
Scott wrote:> Mark...update_without_callbacks does exactly what I needed. Thanks! > > However, I can''t find it mentioned anywhere in the documentation. I > grepped the code and found that it''s set for #:nodoc. > > a) how could i have known this exists without knowing every line of > code? > b) how did you know this exists? > c) why is this method, and others, not included in the docs? someone > had to choose to add #:nodoc to the code...why did they choose to do > that?update_without_callbacks is created using alias_method_chain, so it''s not easy to add to the rdocs, but it should be. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---