
Serial offsets (ex :start-at => 1000)
Reported by ronin-129695 (at lighthouseapp) | February 25th, 2011 @ 11:52 PM
A useful feature for me would be being able to offset the starting value of serial properties.
Use Case:
In my current project we use subsequent ids to track one of our
datamapper classes however we need to start these at a specific
value for backwards compatibility (so that these ids do not overlap
ids previously assigned).
Example:
- Invoice numbers. These almost never start at zero (who wants to
look like they've never had a client before!?). - Product numbers -
Order numbers - etc.
Current Workaround:
Please note this workaround has serious limitations: it is by no means efficient since it requires a MAX sql call before creating each instance and is does not absolutely ensure values in the database are sequential (a programmer could easily create a instance with a specific id). However it does demonstrate the level of cludge necessary at the moment:
class myModel
include DataMapper::Resource
@@id_starting_value = 1000
@@new_id = lambda do |r, p|
max_id = Order.max(:id).to_i
puts max_id
puts max_id > @@id_starting_value
puts (max_id>@@id_starting_value? (max_id+1) : @@id_starting_value)
return (max_id>@@id_starting_value? (max_id+1) : @@id_starting_value)
end
property :id, Integer, :key => true, :required => true, :default => @@new_id
end
Proposed API Change:
To accomplish the same functionality I propose the following optional attribute be added to Serial Properties:
property :id, Serial, :start_at => 1000
The start_at attribute could also make one call to MAX during the first instance creation and increment that value for the duration of the run.
Comments and changes to this ticket
-
ronin-129695 (at lighthouseapp) February 25th, 2011 @ 11:53 PM
Sorry about the formatting of this ticket, didn't realize this was markdown :S
-
ronin-129695 (at lighthouseapp) February 26th, 2011 @ 12:07 AM
oops, that inital workaround had a bug for the new index. I also made it more efficient by moving the MAX sql to a single initial calculation. This may have problems for databases which are not exclusive to the current app, but for simple stuff it works:
Improved Workaround
@@id_starting_value = 1000 @@max_id = 0 @@new_id = lambda do |r, p| puts "test" if @@max_id < @@id_starting_value then max_id = Order.max(:id).to_i @@max_id = (max_id>=@@id_starting_value? (max_id+1) : @@id_starting_value) else @@max_id += 1 end puts @@max_id.to_s return @@max_id end property :id, Integer, :key => true, :required => true, :default => @@new_id
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
People watching this ticket
- Nobody is watching this ticket.