jeremy.maziarz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Nov-06 19:25 UTC
Implementation ideas for a unique identifier
I have an Item model that uses acts_as_nested_set (via better_nested_set plugin) to maintain tree structures of Items. There can potentially be thousands of "root" Items. A requirement is that each "root" Item have a unique identifier in the form ''YYMMDD-nnnnnn'' where nnnnnn is a sequential counter (e.g. 071106-000024). There can be no gaps in this sequential counter. For example, a "root" Item with 57 children is added to the database. The "root" has a unique identifier of ''071106-000001'' because it is the first "root" item (Item#id = 1). The next "root" item (Item#id 58) must have a unique identifier of ''071106-000002'' and NOT ''071106-000058''. How would you implement this "sequential counter"? --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Nov 6, 2007, at 8:25 PM, jeremy.maziarz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:> I have an Item model that uses acts_as_nested_set (via > better_nested_set plugin) to maintain tree structures of Items. There > can potentially be thousands of "root" Items. A requirement is that > each "root" Item have a unique identifier in the form ''YYMMDD-nnnnnn'' > where nnnnnn is a sequential counter (e.g. 071106-000024). There can > be no gaps in this sequential counter. > > For example, a "root" Item with 57 children is added to the database. > The "root" has a unique identifier of ''071106-000001'' because it is > the first "root" item (Item#id = 1). The next "root" item (Item#id > 58) must have a unique identifier of ''071106-000002'' and NOT > ''071106-000058''.The rows have their own regular integer keys, and that''s an additional column that is NULL for non-root nodes? -- fxn --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
jeremy.maziarz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Nov-06 20:45 UTC
Re: Implementation ideas for a unique identifier
Correct. On Nov 6, 3:29 pm, Xavier Noria <f...-xlncskNFVEJBDgjK7y7TUQ@public.gmane.org> wrote:> On Nov 6, 2007, at 8:25 PM, jeremy.mazi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote: > > > I have an Item model that uses acts_as_nested_set (via > > better_nested_set plugin) to maintain tree structures of Items. There > > can potentially be thousands of "root" Items. A requirement is that > > each "root" Item have a unique identifier in the form ''YYMMDD-nnnnnn'' > > where nnnnnn is a sequential counter (e.g. 071106-000024). There can > > be no gaps in this sequential counter. > > > For example, a "root" Item with 57 children is added to the database. > > The "root" has a unique identifier of ''071106-000001'' because it is > > the first "root" item (Item#id = 1). The next "root" item (Item#id > > 58) must have a unique identifier of ''071106-000002'' and NOT > > ''071106-000058''. > > The rows have their own regular integer keys, and that''s an additional > column that is NULL for non-root nodes? > > -- fxn--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
jeremy.maziarz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Nov-06 20:52 UTC
Re: Implementation ideas for a unique identifier
Sometimes writing it out in the form of a question gets the creative juices flowing.What if I added an attribute to the items table named "sequence". Then I could use an after_create callback and two private methods such as: def after_create if self.root? update_attribute(:sequence, generate_sequence) update_attribute(:identifier, generate_identifier) end end private def generate_sequence Item.maximum(:sequence, :conditions => [''parent_id != ?'', ''NULL'']) + 1 end def generate_identifier "#{self.created_on.strftime(''%y%m%d'')}- #{self.sequence.to_s.rjust(6, ''0'')}" end --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
jeremy.maziarz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Nov-06 22:25 UTC
Re: Implementation ideas for a unique identifier
Here is my working solution: class AddSequenceToItems < ActiveRecord::Migration def self.up add_column :items, :sequence, :integer end def self.down remove_column :items, :sequence end end class Item < ActiveRecord::Base def after_create # This item doesn''t already have a root, so this is a new root item update_attribute(:root_id, self.id) if self.root_id.nil? if root? update_attribute(:sequence, generate_sequence) update_attribute(:identifier, generate_identifier) end end def sequence(padded = false) padded ? padded_sequence : self[:sequence] end private def self.maximum_sequence Item.maximum(:sequence) || 0 end def generate_sequence self.class.maximum_sequence + 1 end def generate_identifier "#{self.created_on.strftime(''%y%m%d'')}-#{padded_sequence}" end def padded_sequence(length = 6, str = ''0'') self[:sequence].to_s.rjust(length, str) end end --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
> I have an Item model that uses acts_as_nested_set (via > better_nested_set plugin) to maintain tree structures of Items. There > can potentially be thousands of "root" Items. A requirement is that > each "root" Item have a unique identifier in the form ''YYMMDD-nnnnnn'' > where nnnnnn is a sequential counter (e.g. 071106-000024). There can > be no gaps in this sequential counter. > > For example, a "root" Item with 57 children is added to the database. > The "root" has a unique identifier of ''071106-000001'' because it is > the first "root" item (Item#id = 1). The next "root" item (Item#id > 58) must have a unique identifier of ''071106-000002'' and NOT > ''071106-000058''. > > How would you implement this "sequential counter"?Have a table with two columns. The first is the date. The second is an integer. Write a routine that gets you the next highest value for the given date and then updates the table with that new value for next time. And put a gigantic lock around the entire thing so that you don''t have any race conditions. If it were me, I''d spend some time trying to remove that restriction, but I''m guessing you''re stuck with it. What happens in this situation: - Lock. - Get the next NNNN value. - Update the database for next time. - Unlock. - Try and use it, but it freaks out, entire Rails app crashes. - Restart app. At this point you have a hole in your sequence... how do you even know if you have a hole? What do you do? --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---