2010-06-14 5 views
0

Pour chaque carte, je voudrais joindre un numéro spécial à ceux qui incréments par un.Rédaction d'un simple compteur incrémentiel dans des rails

Je suppose que je peux faire tout cela dans le contrôleur.

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

Or. Je peux être flagrant retardé. Et peut-être que le mieux est d'ajouter une table auto-incrémentielle à mysql. Le problème est le numéro doit commencer à un certain nombre, 1020.

Toutes les idées?

+0

Ruby ne dispose pas d'un opérateur ++ (ou -, pas étonnant!) –

+0

@John Pourquoi dites-vous «sans surprise»? – Trip

+2

car avoir ++ sans - serait bizarre, n'est-ce pas? –

Répondre

1

Personnellement, je ne mettrais pas cette responsabilité sur la base de données, ou le contrôleur; Je l'aime dans le modèle. Quelque chose comme:

/app/modèles/carte

validates_uniqueness_of :special_number 

def before_validation_on_create 
    self.special_number = CardSpecialNumber.next! 
end 

/app/modèles/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 
+1

Si c'est juste un nombre qui doit être incrémenté, je mettrais dans la base de données en utilisant une séquence ou un auto-incrément. La base de données peut le faire beaucoup plus efficace que vous. Je peux imaginer des cas où vous avez besoin de plus de contrôle, par ex. l'ordre est important, aucun trou n'est autorisé, ou un algo- rithme de comptage bizarre (par exemple je dois créer un nombre aaaa-mm-xxxx où xxxx est le nombre pour ce mois ... alors le modèle est en effet le meilleur endroit. code ci-dessus retournera toujours 1020 s'il n'y a pas de ligne initiale disponible – nathanvda

+0

@nathanvda. En ce qui concerne le 1020:. vous avez raison, il retournera 1020 si aucune ligne initiale, mais voyage a demandé que comme une exigence spécifique Face, Je pense que cette exigence (à partir de 1020) a été mon facteur décisif pour contourner la base de données.J'aime le code qui fonctionne avec différentes bases de données, Postgres/sqlite3/sqlsever ont toutes des façons différentes d'incrémenter les commandes multi-base de données. –

+0

Je n'ai qu'un seul modèle pour les cartes, aucun pour le numéro spécial, est-il impératif de les séparer et de faire hériter Card_Special_Number de Card? – Trip

2

Vous pouvez définir (et réinitialiser) la valeur AUTO_INCREMENT de MySQL sur une base par table à l'aide d'un ALTER TABLE statement:

ALTER TABLE mytable AUTO_INCREMENT = 1020 

ALTER TABLE est pas un privilège que vous voulez que tous les utilisateurs ont, voir sur la sécurisation de façon appropriée.

+0

Hmm .. Je ne veux pas modifier la table. Je veux changer la colonne. Pour lequel j'ai essayé, ALTER COLUMN SpecNum AUTO_INCREMENT = 1020. Il a renvoyé une erreur pour la syntaxe SQL – Trip

+0

@Trip: MySQL autorise uniquement une colonne auto_increment par table; vous utilisez uniquement ALTER TABLE pour définir la valeur pour AUTO_INCREMENT, selon le lien de documentation que j'ai fourni. –

+0

Ah, parce que l'autre auto_incrememnter est pour autre chose d'important. Je suppose que je devrais utiliser le modèle après tout. – Trip

Questions connexes