views:

79

answers:

2

For every Card, I would like to attach a special number to them that increments by one.

I assume I can do this all in the controller.

def create
 @card = Card.new(params[:card])
 @card.SpecNum = @card.SpecNum ++
...
end

Or. I can be blatantly retarded. And maybe the best bet is to add an auto-incremement table to mysql. The problem is the number has to start at a specific number, 1020.

Any ideas?

+2  A: 

You can set (and reset) MySQL's AUTO_INCREMENT value on a per table basis using an ALTER TABLE statement:

ALTER TABLE mytable AUTO_INCREMENT = 1020

ALTER TABLE is not a privilege you want all users to have, see about securing it appropriately.

OMG Ponies
Hmm.. I don't want to alter the table. I want to alter the column. To which I tried, ALTER COLUMN SpecNum AUTO_INCREMENT = 1020 . It returned an error for SQL syntax
Trip
@Trip: MySQL only allows one auto_increment column per table; you only use ALTER TABLE to set the value for AUTO_INCREMENT, per the documentation link I provided.
OMG Ponies
Ah, cuz the other auto_incrememnter is for something else important. I guess I should use the model after all.
Trip
+1  A: 

Personally, I wouldn't put that responsibility on the database, or the controller; I like it in the model. Something like:

/app/models/card

validates_uniqueness_of :special_number

def before_validation_on_create
  self.special_number = CardSpecialNumber.next!
end

/app/models/card_special_number

def self.next!
  last_number_holder = CardSpecialNumber.first
  if last_number_holder.nil?
    CardSpecialNumber.create!(:counter => 1020)
    return 1020
  end

  last_number_holder.counter = last_number_holder.counter + 1
  last_number_holder.save!
  last_number_holder.counter
end
Jesse Wolgamott
If it is just a number that needs to be incremented, i would put in the database using a sequence or auto-increment. The database can do it so much more efficient than you. I can imagine cases where you need more control, e.g. order is important, no holes are allowed, or some weird counting-algoritm (e.g. i have to create a number yyyy-mm-xxxx where xxxx is the count for that month... then the model is indeed the best place. BTW the above code will always return 1020 if there is no initial row available.
nathanvda
@nathanvda: Regarding the 1020: you're right, it will return 1020 if no initial row, but Trip requested that as a specific requirement.In face, I think that requirement (starting at 1020) was my deciding factor for bypassing the database. I like code that works with different databases; postgres / sqlite3 / sqlsever all have different ways of doing incrementing. Multi-database commands might be the devil's work.
Jesse Wolgamott
I have just one model for Cards. None for just the special number. Is it imperative to seperate them and make Card_Special_Number inherit from Card?
Trip
I think it would be needed, since that will be the storage for your counter. It'll be a table with just one record in it (columns would be an integer named counter)No inheritance though, they are two separate entities.
Jesse Wolgamott
Almost got this to work. I have a number that increments and whatnot. But strange as it is, I would like it to return this number "294670251400". I replaced that number for 1020. Yet it returns as "2147483647". Weird right? Strange this too is that the number stopped incrementing as well.
Trip
Strange even in IRB. If I update attribute so that counter = 294670251400, it saves true and returns 2147483647 . Soooo strange.
Trip
Ah yes. this is the biggest number mysql can handle.
Trip
ahhhh. ok. so integer is not your friend. try adding :limit => 8 to your migration when creating CardSpecialNumber.counter: http://stackoverflow.com/questions/1066340/how-to-use-long-id-in-rails-applications
Jesse Wolgamott