The system I am building has many users, and each user has it’s own invoice number sequence. Here is the code in it’s entirity:
1 class Invoice < ActiveRecord::Base 2 belongs_to :user 3 4 def self.find_next_available_number_for(user, default=999) 5 (user.invoices.maximum(:no) || default).succ 6 end 7 end
This code is pretty simple to read. In fact, in English, it translates to:
Find the maximum value of no in invoices for user, or use the default value, and then take the successor of this value.
You see, Ruby code is so much more succint !
Anyway, the features used in this article were:
- Integer#succ and String#succ (MySQL does not return the type of the aggregate column, so Rails returns a plain String. Duck typing does the rest)
- ActiveRecord::Associations::HasManyAssociation#method_missing (makes the class methods of the associated class available through the association collection, with a proper scope)