2009-09-20 13 views
1

Puis-je créer un modèle Rails où l'ID s'incrémente automatiquement à partir de 0, pas de 1? Comment? Y a-t-il des pièges? J'ai vérifié ici, et il semble que je ne peux pas:Puis-je créer un modèle Rails où l'ID s'incrémente automatiquement à partir de 0, pas de 1?

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M001911

Si, comme il semble, je ne peux pas, est-il des raisons pour lesquelles je ne peux pas ou ne doit pas seulement affecter manuellement un ID de 0 à la première instance de cette classe? Si c'est le cas, Rails assignera-t-il automatiquement un ID de 1 à l'instance suivante créée?

Répondre

2

ActiveRecord fonctionne sur le principe que chaque table possède une seule colonne de clé primaire qui n'a aucune importance dans le domaine d'application. C'est (en partie) pourquoi vous n'avez pas à définir la colonne id dans vos migrations create_table. Le nom de la colonne (et le type) peuvent être modifiés, en grande partie pour prendre en charge les schémas hérités, et les clés primaires à plusieurs colonnes sont difficiles à implémenter du tout. Au moment où vous commencez à attribuer une signification de domaine à l'identifiant, vous commencez à rompre la convention et je vous conseille vivement de créer un autre champ/propriété/variable-membre/colonne/what-have -vous de détenir cette information. Laissez l'identifiant à une clé. Dans le cas d'utilisation que vous décrivez, il n'y a aucune raison pour que votre contrôleur n'identifie pas le cas particulier où params[:id] == '0' et le traite de manière appropriée, en basculant vers la "partie de projet", que vous identifiez d'une autre manière que par . Puisque vous voulez probablement que chaque projet commence à partir de 0, je suppose que vous ajouteriez quelque chose comme seq et l'utiliserais au lieu de id dans vos routes, de cette façon vos clés params ont plus de sens. Conservez la valeur seq la plus élevée du projet, afin de connaître le numéro à attribuer lors de la création d'une nouvelle pièce. Les suppressions et les insertions (en supposant que la séquence compte) sont entièrement à vous ...

+0

Merci. Je vais essayer. –

5

Pourquoi auriez-vous besoin de faire cela? Dans le modèle Rails, l'identifiant de l'objet représente l'identifiant unique de la base de données qui ne peut jamais être 0 (je parle de mysql, peut-être qu'il y a des exceptions avec des séquences et des séries dans postgres).

+0

Merci Eimantas. J'avais peur de ça. Vous avez demandé pourquoi j'aurais besoin de faire ça? Parce que le modèle est "partie", appartient à "projet". La première partie comme la partie qui englobe le projet dans son ensemble. Le logiciel le crée lorsque l'utilisateur crée un projet, avant que l'utilisateur ne crée lui-même des parties plus petites. Ce serait bien d'une perspective UX si cette partie apparaissait comme "/ part/0" à l'utilisateur dans la barre d'adresse du navigateur, et si l'utilisateur voyait seulement, disons, "/ part/2" s'ils avaient défini 2 parties de leur propre. –

+0

Vous pouvez utiliser un compteur séparé pour chaque pièce au lieu d'utiliser la clé primaire pour cela. Sinon, je garderais la partie 0 (pour l'ensemble du projet) dans l'objet du projet lui-même. – Eimantas

+1

Je parle pour mysql, la valeur par défaut de la colonne auto_increment est 0, donc le premier enregistrement devient 0 + 1 = 1, pour obtenir la valeur "premier enregistrement" de 0, vous devrez par défaut la valeur auto_increment à -1. Alors que -1 + 1 = 0, je doute que cela soit possible. –

0

Pour postgres, vous pourriez vouloir jeter un oeil à la création de la table manuellement, par ex.

class MigrationName < ActiveRecord::Migration 
    def self.up 
    execute <<EOF 

create sequence foos_id_seq start 0 increment 1 no cycle; 
create table foos (
    id  integer not null default nextval('foos_id_seq'), 
    ... 
    primary key(id) 
); 
EOF 
    end 

    def self.down 
    execute <<EOF 
drop table foos; 
drop sequence foos_id_seq; 
EOF 
    end 
end 

Notez que la position de l'EOF est importante.